当它遇到分配给Expression< Func< T>>的lambda时,它是否被硬编码到编译器中以返回表达式树。像下面这样的东西?
表达式< Func< int,int>> exp = n => N;
答案 0 :(得分:2)
来自C#规范(6.1.12):
匿名函数和方法组中没有类型 他们自己,但可能会隐式转换为委托类型或 表达式树类型。
所以匿名函数(lambda)本身没有类型,但是当你将它分配给类型Expression
的变量(或传递给期望Expression
参数的函数)时 - 它被隐式转换它(假设它是可能的 - 不是每个匿名函数都可以转换为表达式树)。与委托相同的故事 - 如果您将其传递给期望Func<int,int>
的函数或分配给此类型的变量 - 它将成为委托而不是表达式树。
答案 1 :(得分:1)
因为lambda被分配给{ name: 'GreenBay', value: '12' }
。
答案 2 :(得分:1)
是的,在第4.6节“表达式树类型”
中的C#5规范文档中4.6表达式树类型
表达式树允许将lambda表达式表示为数据结构而不是可执行文件 码。表达式树是表单的表达式树类型的值System.Linq.Expressions.Expression<D>
,其中D是任何委托类型。 对于本规范的其余部分,我们将参考这些类型 使用简写Expression<D>
。如果转换存在于 lambda表达式为委托类型D,也存在转换 表达式树类型Expression<D>
。而转换一个 lambda表达式为委托类型生成一个委托 引用lambda表达式的可执行代码,转换为 表达式树类型创建表达式树的表示形式 lambda表达式。表达式树是有效的内存数据 lambda表达式的表示形式和 lambda表达透明和显式。就像委托类型一样 D,Expression<D>
据说有参数和返回类型 与D的相同。以下示例表示a lambda表达式作为可执行代码和表达式树。 由于转换存在Func<int,int>
,因此转换也是如此 存在于Expression<Func<int,int>>
:Func<int,int> del = x => x + 1; // Code Expression<Func<int,int>> exp = x => x + 1; // Data
遵循这些分配,委托del引用一个方法 返回
x + 1
,表达式树exp引用数据 描述表达式x => x + 1
的结构。最正确 通用类型Expression的定义以及精确的 lambda表达式时构造表达式树的规则 转换为表达式树类型,都在范围之外 这个规范。有两件事是很重要的:
- 并非所有lambda表达式都可以转换为表达式树。例如,lambda表达式带有语句体和lambda 无法表示包含赋值表达式的表达式。在 在这些情况下,转换仍然存在,但在编译时会失败。 这些例外情况在§6.5中有详细说明。
Expression提供了一个实例方法Compile,它生成一个D类型的委托:
Func<int,int> del2 = exp.Compile();
调用此委托会导致表达式所代表的代码 要执行的树。因此,鉴于上面的定义,del和del2 是等价的,以下两个陈述将具有相同的 效果:
int i1 = del(1); int i2 = del2(1);
执行此代码后,i1和i2都将具有值2。
答案 3 :(得分:0)
来自msdn;
将lambda表达式赋给Expression类型的变量时,编译器会发出代码来构建表示lambda表达式的表达式树。