Jef*_*eff 5 c# dynamic-language-runtime .net-4.0 expression-trees
我对 DynamicMethods、表达式树和 DLR 之间的交互和关系有一些疑问。
我知道 LambdaExpression.Compile 在内部使用 ILGenerator 来创建委托。但是,已编译的 LambdaExpression 和 DynamicMethod 之间存在一些根本差异。例如
A。动态方法调用速度更快
b. 编译后的 LambdaExpression 可以嵌入闭包(ConstantExpressions 是非原始值)
b. 已编译的 LambdaExpression 没有 DeclaringType。
问题:
A。为什么 DynamicMethods 的调用速度比编译的 LambdaExpressions 更快?
b. 允许闭包的已编译 LambdaExpressions 有什么特别之处?当我使用非 ConstantExpression 时,表达式树实际上会生成闭包类吗?如果是这样,这个生成的类去了哪里?
C。编译后的 LambdaExpressions 去哪里(运行时)?对他们的支持在哪里实施?它不能只是 Reflection.Emit,不是吗?
我知道,dynamic 关键字实际上只是一个用于发出 CSharp CallSites、Binder 等的编译器技巧。据我了解,在内部,这些会生成表达式树,并且还使用 C# 编译器的精简版本。
问题
A。生成的表达式树是 CallSiteBinders 的一般函数还是 Microsoft.CSharp dll 中它们的特定实现和用法?
b. 这些表达式树是由 DynamicExpression 节点组成的吗?或者是其他东西?如果有其他原因,为什么?
C。C# 编译器的精简版本在哪里以及为何发挥作用?它与常规调用 LambdaExpression.Compile 或 DynamicMethods 或任何类型的 IL 生成为何以及有何不同?我可以理解如何使用 CallSiteBinders 来构建表达式树,但为什么在发生转换后需要 C# 编译器?一旦它采用表达式树(这只是一个 API)的形式,C# 与它有什么关系呢?
我不太了解dynamic,所以我只回答你问题的第一部分。
为什么 DynamicMethods 的调用速度比编译的 LambdaExpressions 更快?
如果他们是的话,我会感到非常惊讶,因为Expression.Compile()内部使用DynamicMethod.
允许闭包的已编译 LambdaExpressions 有什么特别之处?当我使用非 ConstantExpression 时,表达式树实际上会生成闭包类吗?如果是这样,这个生成的类去了哪里?
这很容易验证。只需查看编译表达式树生成的委托的Target和即可。Method您会注意到Target(以及 的第一个参数Method)是System.Runtime.CompilerServices.Closure。这是一个包含 field 的类object[] Constants,其中ConstantExpression存储 s 的非原始值。
编译后的 LambdaExpressions 去哪里(运行时)?对他们的支持在哪里实施?它不能只是 Reflection.Emit,不是吗?
正如我之前所说,Expression.Compile()内部使用DynamicMethod. 所以,是的,这只是 Reflection.Emit。