Reputation: 255
I have a constructor that takes an Action delegate as argument:
Public Class DelegateCommand
Public Sub New(execute As Action(Of T))
Me.New(execute, Nothing)
End Sub
End Command
' This works as expected
Dim executeIsCalled = False
Dim command = New DelegateCommand(Sub() executeIsCalled = True)
command.Execute(Nothing)
Assert.IsTrue(executeIsCalled) ' Pass
Action does not have a return value and the MSDN states that I must use a Sub for this purpose (MSDN Action Delegate). However this is not true as it is perfectly possible to use a function delegate:
Dim executeIsCalled = False
Dim command = New DelegateCommand(Function() executeIsCalled = True)
command.Execute(Nothing)
Assert.IsTrue(executeIsCalled) ' Fail
This compiles fine, however the executeIsCalled = True
is interpreted as the return statement, leading to the unexpected result that executeIsCalled
is remains false.
Interestingly, you can do the following:
Dim executeIsCalled = False
Dim command = New DelegateCommand(Function()
executeIsCalled = True
Return False
End Function)
command.Execute(Nothing)
Assert.IsTrue(executeIsCalled) ' Pass
How can I prenvent that mistakenly a Function lambda expression is used?
Upvotes: 4
Views: 2335
Reputation: 5737
This might not perfectly solve your needs because the compiler won't help you - but at least you will discover the errors in runtime and not wonder why any variables are not set correctly.
You could use a Delegate
instead of a Action<>
as constructor argument. Unfortunately, VB.NET will still allow any other devs to pass in Sub()
and Function()
lambdas. However, you can check the ReturnType
in runtime and throw an exception if it is not Void
.
Public Class DelegateCommand
Public Sub New(execute As [Delegate])
If (Not execute.Method.ReturnType.Equals(GetType(Void))) Then
Throw New InvalidOperationException("Cannot use lambdas providing a return value. Use Sub() instead of Function() when using this method in VB.NET!")
End If
execute.DynamicInvoke()
End Sub
End Class
Void
is coming from the C#-world and is mostly unknown by VB.NET-devs. There, it is used to write methods without an return value (VB: Subs) like any other method returning a value (VB: Functions).
private void MySub()
{
// ...
}
private bool MyFunction()
{
return true;
}
Upvotes: 2