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

问题描述 投票:0回答:1

我想要几个使用表达式树动态创建的例程。似乎使用它们的最简单方法是创建

LambdaExpression
然后调用
LambdaExpression

Compile()
产生可调用委托。

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

有任何建议欢迎提出!

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