2010-11-16 110 views
2

我有一個像瞭解以下拉姆達

void Test(Func<bool> f) 
{ 
    f.Invoke(); 
} 

的方法我通過在Test(()=>GetItem("123"))

f.Invoke()居然叫GetItem("123")

我想知道f怎麼知道GetItem有一個參數?

回答

2

您傳遞給Test的是parameter-less delegate,它調用您的GetItem方法。 所以你的Test方法不知道任何關於參數GetItem。它只知道它所調用的delegate

Test(()=>GetItem("123")) 

等於

Test(delegate { return GetItem("abc") ; }); 

這就好比打電話

Test(MyMethod) 
... 
bool MyMethod() 
{ 
    return GetItem("123"); 
} 
+0

我認爲你的意思'測試(的MyMethod)'和'布爾的MyMethod(){返回的GetItem( 「123」 );在最後一個塊中。 – jason 2010-11-16 06:00:16

+0

它認爲問題在我發佈答案後進行了編輯。我現在編輯了我的答案。 – 2010-11-16 06:05:06

3

你的問題有點混亂。 F不知道Getitem需要什麼。

當您創建lambda時,「指針」返回到方法所在內存的位置。該方法包含一行代碼返回Getitem(「123」)。 當你調用F時,實際發生的是一種跳轉到指針。 F就像是指向函數所在內存中那個地方的「指針」。因此,要回答你的問題,F不知道Getitem需要什麼,F只是調用你寫的函數,並且該函數具有硬編碼的「123」參數。

記住拉姆達是一種類型的Delegate

4

你的功能Test接受一個函數作爲參數。它會調用傳入的任何函數作爲參數。

在這種情況下,當您創建lambda () => GetItem("123")時,您正在創建一個不帶參數的函數,並調用GetItem("123")

Test不知道傳遞給GetItem的參數的值,也不需要,因爲該參數的值在lambda中被硬編碼。

2

好問題。你可以把委託

() => GetItem("123") 

的爲下面的表達式樹

Expression.Lambda<Func<bool>>(
    Expression.Call(
     null, 
     typeof(X).GetMethod("GetItem"), 
     new Expression[] { Expression.Constant("123", typeof(string)) } 
    ), 
    new ParameterExpression[0] 
); 

在這裏,我假設GetItem的編譯版本,是一類X,並且它的返回類型是定義的方法宣佈爲bool

問題是代理捕獲所有需要調用的信息。當您在Test中調用此代理時,您不知道方法GetItem在幕後,或者它正在使用參數"123"調用。代表正在跟蹤這些信息,並且Test對這些詳細信息是不可知的。它只是想要它可以調用的東西,最終返回bool。在你的特定情況下,bool恰好是GetItem("123")的結果。

f.Invoke()居然叫GetItem("123")

其實事實並非如此。它叫做() => GetItem("123"),它只返回GetItem("123")的值。看到不同?