将lambda表达式转换为表达式树

时间:2011-12-07 18:10:49

标签: linq lambda

从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<T>上运行的LINQ语句使用的lambda表达式只能包含一个表达式,这是由于它的重要性只有一个表达式可以转换为表达式树吗?

谢谢

2 个答案:

答案 0 :(得分:15)

它不仅仅是它们只能包含一个表达式 - 它根本不能是语句lambda 。即使像这样的块:

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

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

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

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

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

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

  

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

答案 1 :(得分:1)

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