【问题标题】:Difference between Expression<Func<>> and Func<> [duplicate]Expression<Func<>> 和 Func<> 之间的区别 [重复]
【发布时间】:2011-02-09 12:38:17
【问题描述】:

举个例子,为什么大多数 LINQ 运算符都接受Expression&lt;Func&lt;TSource&gt;&gt; 及其等效的Func&lt;TSource&gt;

使用通用 Expression 类而不是直接使用 lambda 语法有什么好处/原因?

【问题讨论】:

    标签: c# linq


    【解决方案1】:

    使用Expression&lt;T&gt; 可以显式创建expression tree - 这意味着您可以像处理数据一样处理构成查询的代码。

    原因是 LINQ 提供程序(例如 LINQ to SQL)检查查询本身以确定将 C# 表达式转换为 T-SQL 查询的最佳方式。由于表达式树允许您将代码视为数据,因此提供者能够做到这一点。

    【讨论】:

    • 不要忘记,表达式树不再是 LINQ 提供者独有的——例如,它们是动态语言运行时的主要基础概念之一。
    【解决方案2】:

    总的来说,两者的主要区别如下:

    • Expression&lt;Func&lt;...&gt;&gt; 是一个表达式树,它代表了原始源代码(它存储在一个树状数据结构中,非常接近原始 C# 代码)。在这种形式中,您可以分析源代码,并且 LINQ to SQL 等工具可以将表达式树(源代码)翻译成其他语言(例如,在 LINQ to SQL 的情况下为 SQL,但您也可以针对例如 JavaScript)。

    • Func&lt;...&gt; 是您可以执行的普通委托。在这种情况下,编译器将函数体编译为中间语言(IL),就像编译标准方法时一样。

    值得一提的是,Expression&lt;..&gt; 有一个Compile 方法在运行时编译表达式并生成Func&lt;...&gt;,所以从第一个转换到第二个(有一些性能成本)。但是,从第二个到第一个没有转换,因为一旦你得到了IL,就很难(不可能)重构原始源代码。

    【讨论】:

    • 这是否意味着在使用表达式树时会在运行时进行某种编译,还是通常仅用于将代码树翻译成另一种语言?
    • @Rodi:表达式树可以以两种方式使用。通常,它被翻译成其他语言(例如 SQL),但也可以编译它。不过,我还没有看到很多需要编译表达式树的提供程序。
    • 所以这意味着当您在 = 的 RHS 上声明一个 lambda 时,编译器实际上是在查看 LHS 以决定是否应该编译该 lambda 或将其保留为表达式树?
    【解决方案3】:

    Func&lt;T&gt; 创建一个可执行函数。

    Expression&lt;Func&lt;T&gt;&gt; 创建一个表达式树,允许您将函数中的代码用作数据。

    表达式树允许您通过从 .NET 代码生成底层调用来执行 LINQ to SQL 和 LINQ to XML 之类的操作。

    【讨论】:

    • 感谢您使用更少的词;)
    • @jolySoft 字数更少。 :)
    【解决方案4】:

    Expression&lt;Func&lt;&gt;&gt; 表示尚未转换为代码的函数。 Func&lt;&gt; 是一个实际的可执行函数。使用前者允许您在调用它时将表达式转换为适当的函数。例如,对于 LINQ to SQL,这会将其转换为等效代码以执行 SQL 语句并返回指定的内容。使用 LINQ to 对象,它将使用 CLR 在客户端上执行代码。 Func&lt;&gt; 总是在 CLR 中执行——它是可执行代码。

    【讨论】:

      猜你喜欢
      • 2019-01-03
      • 1970-01-01
      • 2013-10-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多