【问题标题】:Converting lambda expression into an expression tree将 lambda 表达式转换为表达式树
【发布时间】:2012-01-15 06:12:18
【问题描述】:

深入了解 C#:

并非所有 lambda 表达式都可以转换为表达式树。你 不能用一组语句转换 lambda(即使只有一个 return 语句 ) 到表达式树中 --> 它必须是形式 只计算一个表达式。

由于 Linq-to-Object 语句不会转换为表达式树对象,因此与 Linq-to-Object 运算符一起使用的 lambda 表达式可以包含语句块

        string[] count = { "one ", "two ", "three ", "four ", "five ", "six " };
        IEnumerable<int> result = count.Select(item =>
                               {
                                   Console.WriteLine(item);
                                   return item.Length;
                               });
        foreach (int i in result);

输出:

one two three four five six

我还没有开始学习 Linq-To-Sql 或 Linq-To-Entities,但我假设与在 IQueryable&lt;T&gt; 上运行的 LINQ 语句一起使用的 lambda 表达式只能包含一个表达式,因为只有单个表达式可以转换成表达式树吗?

谢谢

【问题讨论】:

    标签: linq lambda


    【解决方案1】:

    不仅仅是它们只能包含一个表达式——它根本不可能是一个语句 lambda。甚至是这样的块:

    var result = query.Select(item => { return item.Length; });
    

    对于 LINQ to SQL 无效。它必须表示为:

    var result = query.Select(item => item.Length);
    

    (我刚刚注意到这是你引用的那本书的一部分。哦,好吧 - 这表明我是一致的 :)

    请注意,从 .NET 4 开始,表达式树本身确实能够包含块,但 C# 编译器无法将语句 lambda 转换为那种表达式树。还有其他限制,但它们很少引起问题。

    这是在 C# 4 规范的第 4.6 节中指定的:

    并非所有匿名函数都可以表示为表达式树。例如,不能表示具有语句体的匿名函数和包含赋值表达式的匿名函数。在这些情况下,转换仍然存在,但会在编译时失败。

    【讨论】:

    • 现在,究竟会知道C# in Depth中提到的东西?哦,没关系。
    • @Jon:我突然想到这个问题与stackoverflow.com/questions/8405423/…的问题有多么密切相关。wink wink
    • 乔恩,你说它不能是语句 lambda 是什么意思?该问题显示了使用语句 lambda 的示例代码,它输出了正确的值。
    • @Nick:它使用语句 lambda... 但将其转换为委托,而不是表达式树。
    • 表达式树不执行代码而是生成数据,稍后您可以将其编译回代码。
    【解决方案2】:

    你是对的,它们只能包含一个表达式。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-11-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-07
      • 1970-01-01
      相关资源
      最近更新 更多