2015-12-02 63 views
3

我有一个构造函数的Action委托作为参数:Action委托接受函数lambda表达式

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 

行动没有返回值和MSDN指出,我必须使用一个子为此目的(MSDN Action Delegate)。

Dim executeIsCalled = False  
Dim command = New DelegateCommand(Function() executeIsCalled = True) 
command.Execute(Nothing) 
Assert.IsTrue(executeIsCalled) ' Fail 

编译没有问题,但是executeIsCalled = True被解释为return语句,导致意外结果executeIsCalled仍然是假: 然而,因为它是完全有可能用一个函数委托,这是不正确的。 有趣的是,你可以做到以下几点:

Dim executeIsCalled = False 
Dim command = New DelegateCommand(Function() 
              executeIsCalled = True 
              Return False 
             End Function) 
command.Execute(Nothing) 
Assert.IsTrue(executeIsCalled) ' Pass 

我怎样才能稳定,防止因误操作而一个功能lambda表达式中使用?

+0

给出完整的代码(DelegateCommand类+命令实例化)。 +什么是p参数用于? –

+0

我更新了问题 –

+0

第二个片段('Function()executeIsCalled = True')是一个lambda表达式,而第三个片段('Function()... End Function')是一个匿名函数,它是两个不同的东西 –

回答

2

这可能不能完美地解决您的需求,因为编译器不会帮助您 - 但至少您会发现运行时错误,而不会理解为什么没有正确设置任何变量。

您可以使用Delegate而不是Action<>作为构造函数参数。不幸的是,VB.NET仍然允许任何其他开发者通过Sub()Function() lambda。但是,您可以在运行时检查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,开发者。在那里,它用来写入没有返回值(VB:Subs)的方法,就像返回值(VB:Functions)的任何其他方法一样。

private void MySub() 
{ 
    // ... 
} 

private bool MyFunction() 
{ 
    return true; 
} 
相关问题