【发布时间】:2010-11-21 14:20:43
【问题描述】:
我会保持简单,
如何从 lambda 中获取表达式树??
还是来自查询表达式?
【问题讨论】:
标签: c# lambda expression-trees
我会保持简单,
如何从 lambda 中获取表达式树??
还是来自查询表达式?
【问题讨论】:
标签: c# lambda expression-trees
您必须将 lambda 分配给不同的类型:
// 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<> 类型,就无法取回表达式树。
【讨论】:
f 是代表。但是x => x * 2 是一个 lambda 表达式(正如您自己指出的那样)。你的评论暗示我说了一些不同的东西,但我真的没有。
x => x * 2 可以同时分配给Func<int,int> 和Expression<Func<int,int>>? x => x * 2 的 CLR 类型是什么?这是否意味着Func<int,int> 和Expression<Func<int,int>> 派生自同一个基类型?
Func<a, b> 和 Expression<Func<a, b>> 不必从相同的基类型派生,当您说 int x = 42 和 float y = 42 时,int 和 float 不必从相同的基类型派生
康拉德的回答是准确的。您需要将 lambda 表达式分配给 Expression<Func<...>>,以便编译器生成表达式树。如果你得到一个 Func<...>、Action<...> 或其他委托类型的 lambda,那么你所拥有的只是一堆 IL 指令。
如果您确实需要能够将 IL 编译的 lambda 转换回表达式树,则必须对其进行反编译(例如,执行 Lutz Roeder 的 Reflector 工具所做的事情)。我建议您查看Cecil 库,它提供了高级 IL 操作支持,可以为您节省相当多的时间。
【讨论】:
只是为了扩展 Konrad 的答案并纠正 Pierre,您仍然可以从 IL 编译的 lambda 生成表达式,尽管它不是非常优雅。扩充康拉德的例子:
// Gives you a lambda:
Func<int, int> f = x => x * 2;
// Gives you an expression tree:
Expression<Func<int, int>> g = x => f(x);
【讨论】: