是什么让 C# 编译器输出表达式树而不是代码?
What makes the C# compiler output an expression tree instead of code?
这是代码。
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被直接创建为表达式树(而不是代码)。
是什么让编译器在这两种情况下生成表达式树而不是代码,还有其他有趣的情况吗?
原因:我想在运行时'pick apart'表达式树的顶层,然后编译执行下层。我无法让编译器按照我的方式做事!
Enumerable
的 Select
method accepts a parameter of type Func<TSource,TResult>
. Queryable
's Select
方法接受 Expression<Func<TSource,TResult>>
.
类型的参数
就这么简单 - 如果编译器有一个 lambda 表达式,它可以生成一个表达式或编译 lambda,这个决定取决于它被要求创建的内容 - 如果它是一个 Expression
某种类型的,它将生成表达式树。如果它是 Func
或其他委托类型,它会生成代码。
这是代码。
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被直接创建为表达式树(而不是代码)。
是什么让编译器在这两种情况下生成表达式树而不是代码,还有其他有趣的情况吗?
原因:我想在运行时'pick apart'表达式树的顶层,然后编译执行下层。我无法让编译器按照我的方式做事!
Enumerable
的 Select
method accepts a parameter of type Func<TSource,TResult>
. Queryable
's Select
方法接受 Expression<Func<TSource,TResult>>
.
就这么简单 - 如果编译器有一个 lambda 表达式,它可以生成一个表达式或编译 lambda,这个决定取决于它被要求创建的内容 - 如果它是一个 Expression
某种类型的,它将生成表达式树。如果它是 Func
或其他委托类型,它会生成代码。