2009-08-21 108 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