2015-12-02 57 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; 
} 
相關問題