我有一个构造函数,它将Action委托作为参数:
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没有返回值,MSDN声明我必须为此目的使用Sub(MSDN Action Delegate).
但事实并非如此,因为完全可以使用函数委托:
Dim executeIsCalled = False
Dim command = New DelegateCommand(Function() executeIsCalled = True)
command.Execute(Nothing)
Assert.IsTrue(executeIsCalled) ' Fail
这编译得很好,但是executeIsCalled = True被解释为return语句,导致executeIsCalled保持为false的意外结果.
有趣的是,您可以执行以下操作:
Dim executeIsCalled = False
Dim command = New DelegateCommand(Function()
executeIsCalled = True
Return False
End Function)
command.Execute(Nothing)
Assert.IsTrue(executeIsCalled) ' Pass
我如何预先错误地使用函数lambda表达式?
最佳答案 这可能无法完美地解决您的需求,因为编译器无法帮助您 – 但至少您会在运行时发现错误,并且不知道为什么没有正确设置任何变量.
您可以使用代理而不是操作<>作为构造函数参数.不幸的是,VB.NET仍然允许任何其他开发人员传入Sub()和Function()lambdas.但是,您可以在运行时检查ReturnType,如果它不是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来自C#-world,而VB.NET-devs大多都不知道.在那里,它用于编写没有返回值的方法(VB:Subs),就像返回值的任何其他方法一样(VB:Functions).
private void MySub()
{
// ...
}
private bool MyFunction()
{
return true;
}