试图理解表达式树是什么

时间:2011-10-18 14:54:15

标签: c# delegates lambda expression-trees

以下两个片段的产品输出相同。 我理解Func如何用单个参数封装一个方法,并返回一个bool值。你可以指定一个 方法,匿名方法或lambda表达式。

Func<int, bool> deleg = i => i < 5;
Console.WriteLine("deleg(4) = {0}", deleg(4));

下面是使用我还不完全了解的表达式树。我为什么要这样做呢?它更灵活,它给我带来了什么好处?

System.Linq.Expressions.Expression<Func<int, bool>> expr = i => i < 5;
Func<int, bool> deleg2 = expr.Compile();
Console.WriteLine("deleg2(4) = {0}", deleg2(4));

4 个答案:

答案 0 :(得分:5)

基本上,Expression树是lambda表达式的主体,允许你

  • 反省表达(参见其中的内容所以说)
  • 操纵表达式(简化,扩展(例如添加新功能或修改以处理不同的项目)。

表达式为Compile()后,只是另一个委托,您只能调用,而不是检查或修改。

每当你想要

  • 动态创建表达式(我的意思是:构造,而不是分配)
  • 动态处理表达式

Function<>类型还不够。

答案 1 :(得分:1)

表达式树的关键是你可以用它们做更多的事情,而不仅仅是将它们编译成一个函数。您可以检查它们,修改它们并将它们编译为除.net函数之外的其他内容。

例如,Linq2SQL将表达式树编译为SQL代码。你不能用普通的.net函数做到这一点。

答案 2 :(得分:1)

在你的第一个例子中,你只需要“硬编码”函数的主体并将其分配给一个代理。

在你的第二个例子中,赋值构造了一个表达式树,它是一个对象模型,用于在内存中的数据结构中代表你的代码。

优点是您可以修改和检查该数据结构。

例如,LINQ2SQL使用该技术将表达式转换为另一种称为SQL的语言。

答案 3 :(得分:0)

表达式树是常规的内存中数据结构,可以通过编程方式遍历,并且这种遍历的结果可能是某些内容,例如您要发送到数据库的查询。阅读ExpressionVisitor课程的更多内容,了解它是如何完成的。

另一方面,编译的函数只不过是一系列CIL代码。您仍然可以以编程方式检查它,但您不是在检查定义,而是检查它的编译器输出。