LambdaExpression.Compile() 是否创建动态加载的额外程序集?

Rex*_*ski 1 .net clr expression

我想要几个使用表达式树动态创建的例程。似乎使用它们的最简单方法是创建LambdaExpression然后调用LambdaExpression.
Compile()产生一个可调用的委托。

  1. 这种解决方案可能会带来哪些性能损失?
  2. 编译过程中到底发生了什么?
  3. 是否创建并动态加载了具有额外新类类型的额外程序集?
  4. 每次我打电话时都会发生这种情况吗Compile()
  5. TypeBuilder使用and创建一个新类型并包含所有例程作为该类型的静态方法是否更好MethodBuilder

欢迎任何建议!

Mar*_*ell 5

  1. 发出阶段、反射启动的委托创建(实际上只是构建表达式树)相对昂贵;如果你每次都这样做,就会受伤;但是,如果您有效地缓存策略(这样您就不会构建表达式树并不断编译它),那么它是非常好的并且是进行元编程的合理方法
  2. 通常,会生成 a - 这是一个独立的方法,避免了、等DynamicMethod所有常见的权重,并且提供对a风格方法的原始访问;然后代码遍历表达式树,通过 ; 发出适当的操作码。最后,被称为AssemblyBuilerModuleBuilderTypeBuilderILGeneratorstaticILGeneratorCreateDelegateDynamicMethod
  3. 不; DynamicMethod试图避免这种情况
  4. 是的; 所以尝试缓存你的策略
  5. 取决于上下文;有些事情DynamicMethod可以做但TypeBuilder不能做(例如,可访问性跳过),有些事情TypeBuilder可以做但DynamicMethod不能做(实现接口、声明和使用字段等);如果你不需要这些东西,Expression.Compile()这是避免学习低级引用发出的一个很好的方法,这很容易出错(并且无效的 IL 通常会杀死运行时)
  6. (你没有问 6,但是......)还应该注意的是,Expression可以选择通过 AST 解释器实际运行来欺骗发射,而不是在不允许引用发射的运行时;Compile()返回此解释器的入口点,而不是动态编译方法的委托;如果您使用此选项,则此选项不可用TypeBuilder