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

Expression.Lamda is not working with dynamically generated class

这里是示例代码做测试:

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);

这里我得到一个例外

Specified method is not supported

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

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

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

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

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

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