I'm trying to write a custom contrain for nunit (3) in vb.net Simplest example (following the docs) would be:
Namespace MYConstraints
Public Class MyConstraint
Inherits NUnit.Framework.Constraints.Constraint
Public Overrides Function ApplyTo(Of TActual)(actual As TActual) As NUnit.Framework.Constraints.ConstraintResult
Throw New NotImplementedException()
End Function
End Class
End Namespace
(The ApplyTo
definition was added by Visual Studio automatically even, when I inherited the nunit Constraint
class)
Problem is, it won't compile!
I get two errors:
BC30518 Overload resolution failed because no accessible 'That' can be called with these arguments:
'Public Shared Overloads Sub That(Of TActual)(del As ActualValueDelegate(Of TActual), expr As IResolveConstraint)': Type parameter 'TActual' cannot be inferred.
'Public Shared Overloads Sub That(Of TActual)(actual As TActual, expression As IResolveConstraint)': Type parameter 'TActual' cannot be inferred.
And
BC30935 Member 'Public MustOverride Overloads Function ApplyTo(Of TActual)(actual As TActual) As ConstraintResult' that matches this signature cannot be overridden because the class 'Constraint' contains multiple members with this same name and signature:
'Public MustOverride Overloads Function ApplyTo(Of TActual)(actual As TActual) As ConstraintResult' 'Public Overridable Overloads Function ApplyTo(Of TActual)(ByRef actual As TActual) As ConstraintResult'
Looking at the nunit source for the Constain class
I see that they have defined two variants with the same signature:
/// <summary>
/// Applies the constraint to an actual value, returning a ConstraintResult.
/// </summary>
/// <param name="actual">The value to be tested</param>
/// <returns>A ConstraintResult</returns>
public abstract ConstraintResult ApplyTo<TActual>(TActual actual);
/// <summary>
/// Applies the constraint to an ActualValueDelegate that returns
/// the value to be tested. The default implementation simply evaluates
/// the delegate but derived classes may override it to provide for
/// delayed processing.
/// </summary>
/// <param name="del">An ActualValueDelegate</param>
/// <returns>A ConstraintResult</returns>
public virtual ConstraintResult ApplyTo<TActual>(ActualValueDelegate<TActual> del)
{
#if ASYNC
if (AsyncInvocationRegion.IsAsyncOperation(del))
using (var region = AsyncInvocationRegion.Create(del))
return ApplyTo(region.WaitForPendingOperationsToComplete(del()));
#endif
return ApplyTo(GetTestObject(del));
}
One is abstract with a pass-by-value parameter and the other is virtual with a reference param, but that's surely not enough to distinguish them when calling?
The tooltip error in Visual Studio (VS 2015 Professional if it makes a difference) is:
So it looks like it's interpreting the
ActualValueDelegate<TActual>
as a ByRef TActual
in vb.net
So, two questions:
How is this possible? (Is this allowed in C# but not vb.net? or have I misunderstood something?) - this is just that I am curious :)
How should I write a custom constrain in vb.net? (Does anyone have an example?) This is my main question :)
I'm increasingly convinced this is a bug - something valid in C# that doesn't translate to vb.net maybe. Have created a bug at https://github.com/nunit/nunit/issues/2263