2009-08-21 71 views

回答

50

您必須將拉姆達分配給不同的類型:

// Gives you a delegate: 
Func<int, int> f = x => x * 2; 
// Gives you an expression tree: 
Expression<Func<int, int>> g = x => x * 2; 

同樣爲方法的參數。但是,一旦將這樣的lambda表達式分配給了Func<>類型,就不能得到表達式樹。

+3

在第一種情況下,代表是比lambda更好的術語。兩者都是lambda表達式,一個隱式轉換爲匿名委託,另一個表達式樹。 – nawfal 2013-12-18 15:34:47

+0

@nawfal *'f' *是一個代表。但是'x => x * 2'是一個lambda表達式(就像你自己記下的那樣)。你的評論意味着我說了一些不同的東西,但我確實沒有。 – 2013-12-18 15:59:03

+1

你說第二個表達式給你一個表達式樹。類似的,第一個lambda表達式應該*給你一個委託*,而不是* lambda * - 這是你的第一個評論。不要挑剔,只是提及以便在將來幫助某人。 – nawfal 2013-12-18 16:02:06

10

康拉德的回答是確切的。您需要將lambda表達式分配給Expression<Func<...>>以便編譯器生成表達式樹。如果您得到的lambda爲Func<...>Action<...>或其他委託類型,那麼您擁有的只是一堆IL指令。

如果您確實需要能夠將IL編譯的lambda轉換回表達式樹,則必須對其進行反編譯(例如,執行Lutz Roeder的Reflector工具)。我建議看看Cecil庫,它提供了先進的IL操作支持,可以爲您節省相當長的一段時間。

6

爲了擴大Konrad的答案並糾正Pierre,你仍然可以從IL編譯的lambda生成一個表達式,儘管它並不優雅。增加Konrad的例子:

// Gives you a lambda: 
Func<int, int> f = x => x * 2; 

// Gives you an expression tree: 
Expression<Func<int, int>> g = x => f(x); 
+11

這**不會給你表達樹的原始lamda,它給你一個**新的表達樹,調用委託。而已。 – Aidiakapi 2013-04-16 12:11:44

+0

這個問題不是特定於獲得*等價*表達式。對於內存中的LINQ,這提供了相同的功能。當然,它不能被任何LINQ提供者正確解析。 – joniba 2017-08-29 10:52:54