【问题标题】:Trying to understand what an expression tree is试图理解什么是表达式树
【发布时间】:2011-10-18 14:54:14
【问题描述】:

下面的两个 sn-ps 产生相同的输出。 我了解 Func 如何用单个参数封装方法,并返回一个布尔值。你可以给它分配一个 方法、匿名方法或 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));

【问题讨论】:

    标签: c# delegates lambda expression-trees


    【解决方案1】:

    基本上,表达式树是 lambda 表达式的主体,它允许您

    • 内省表达式(看看里面有什么可以这么说)
    • 操作表达式(简化、扩展(例如添加新功能或修改以处理不同的项目)。

    一旦你Compile() 表达式,它只是另一个委托,你只能调用,不能检查或修改。

    随时随地

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

    Function&lt;&gt; 类型不够用。

    【讨论】:

      【解决方案2】:

      表达式树的意义在于你可以用它们做更多的事情,而不仅仅是将它们编译成一个函数。您可以检查、修改它们并将它们编译为 .net 函数以外的东西。

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

      【讨论】:

      • 你如何检查它们?这个过程叫什么?例子?
      • @codecompleting:使用Expression class及其subclasses的方法和属性。例如,您可以在this article 中看到一个小示例。
      【解决方案3】:

      在您的第一个示例中,您只是“硬编码”了函数的主体并将其分配给了一个委托。

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

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

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

      【讨论】:

        【解决方案4】:

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

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

        【讨论】:

          猜你喜欢
          • 2021-12-19
          • 2012-09-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-09-19
          • 1970-01-01
          相关资源
          最近更新 更多