C# 是什么使C编译器输出表达式树而不是代码?

C# 是什么使C编译器输出表达式树而不是代码?,c#,linq,expression-trees,iqueryable,C#,Linq,Expression Trees,Iqueryable,这是代码 int[] data = new int[] { 1, 2, 3, 4, 5 }; var q1 = data.Select(x => 10 * x); var q2 = data.AsQueryable().Select(x => 10 * x); Expression<Func<int,int>> qe = (x) => 10 * x; 在第一种情况下,编译器生成代码来计算表达式。输出中没有表达式树 在第二种情况下,它生成

这是代码

  int[] data = new int[] { 1, 2, 3, 4, 5 };
  var q1 = data.Select(x => 10 * x);
  var q2 = data.AsQueryable().Select(x => 10 * x);
  Expression<Func<int,int>> qe = (x) => 10 * x;
在第一种情况下,编译器生成代码来计算表达式。输出中没有表达式树

在第二种情况下,它生成一个在调试时可见的表达式树,在运行时编译并执行该树以执行查询,并执行完全相同的操作

在第三种情况下,与2相同的lambda直接作为表达式树而不是代码创建

是什么让编译器在这两种情况下生成表达式树而不是代码,还有其他有趣的情况吗

原因:我想在运行时“分离”表达式树的顶层,然后编译并执行底层。我很难让编译器按我的方式运行

Enumerable的方法接受Func类型的参数。Queryable的方法接受表达式类型的参数


就这么简单-如果编译器有一个lambda表达式,它可以生成一个表达式或编译lambda,并且这个决定是基于它被要求创建的内容-如果它是某种类型的表达式,它将生成表达式树。如果是Func或其他委托类型,则生成代码。

编译器就是这样编写的。它需要这样做才能使表达式工作。这就像return-IEnumerable可以使用yield-return的方法一样。支持语言功能的特殊编译器操作。列表如下。编译器以不同的方式处理可为null的类型。它可以对foreach循环使用duck类型。LINQ查询实际上只是重新安排的方法,通常是扩展方法,但不需要这样做。使用语句仅适用于一次性用品等。您的第一个语句实际上不是一个表达式;这是一个构造函数调用。这两个Select语句是Linq语句,它们在正常操作中生成表达式。第四条语句生成一个表达式,因为您指定了一个表达式作为结果类型。非常不清楚您有什么问题-如果代码像您使用的那样要求表达式,编译器显然会构造表达式树。。。那么,你到底有什么问题呢?谢谢所有这些问题,但都没有回答这个问题:决定编译器将为lambda选择哪条路径的关键特性是什么?该死!真的就这么简单!如果参数派生自委托,编译器将生成代码;如果参数派生自表达式,编译器将生成表达式树,并且没有其他选择。谢谢请记住,委托可以跨越多行,但表达式树的编写方式与委托相同,例如表达式lambda==>newint[]{1,2,3,4,5};只能是一行。
  int[] data = new int[] { 1, 2, 3, 4, 5 };
  var q1 = data.Select(x => 10 * x);
  var q2 = data.AsQueryable().Select(x => 10 * x);
  Expression<Func<int,int>> qe = (x) => 10 * x;