Expression.Lamda 不适用于动态生成的类

本文关键字:动态 Lamda 不适用 适用于 Expression | 更新日期: 2023-09-27 17:57:03

下面是示例代码do test:

var assembly = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("asm"), AssemblyBuilderAccess.Run);
var builder = assembly.DefineDynamicModule("MainModule");
Type type = builder.DefineType("newType");
var parameter = Expression.Parameter(type);
Console.WriteLine(type);
var expr = Expression.Lambda(Expression.Constant(1), parameter);

在这里我得到一个例外

不支持指定方法

我怎样才能避免它?我没有这种类型的编译时,我想通过使用 Expression s 而不是手动发出它来创建构造函数。甚至可能吗?我用实例方法做到了,但我在不使用 this 的情况下做到了。现在我需要它,但如果在施工期间禁止访问类型。

Expression.Lamda 不适用于动态生成的类

好吧,我为此找到了一个优雅的解决方法。

  • 首先,我们只创建一个基类,在我的例子中是:

    public abstract class AsyncClientBase
    {
        protected readonly IAsyncRequestProcessor Processor;
        protected AsyncClientBase(IAsyncRequestProcessor processor)
        {
            Processor = processor;
        }
    }
    
  • 然后我们可以在表达式中使用字段(因为基类型是已经建成)。

  • 然后我们使用 Emit 来创建传递参数构造函数(下面是一个示例)
  • 最后,我们只需在 T 的基类型上更改方法中this参数的类型T(有一个隐式转换子 -> base,所以没关系),并且我们能够在生成的方法中使用字段。

这是一个完整的代码(参见ServiceClientHelpers.XLambdaExpressionHelper.EmitHelper)。