简体   繁体   中英

Expression.Lamda is not working with dynamically generated class

Here is sample code 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);

Here I get an exception

Specified method is not supported

How can I avoid it? I don't have this type an compile-time, and I want to create a constructor by using Expression s instead of Emitting it manually. Is it even possible? I did it with instance methods, but I did it without using this . Now I need it, but access to type if forbidden while it is under construction.

Well, I found an elegant workaround for this.

  • Firstly, we just create a base class, in my case it was:

     public abstract class AsyncClientBase { protected readonly IAsyncRequestProcessor Processor; protected AsyncClientBase(IAsyncRequestProcessor processor) { Processor = processor; } } 
  • Then we can use fields in our expressions (because base type is already builded).

  • Then we use Emit to create pass-params constructors ( here is an example)
  • Finally, we just change type T of this parameter in methods on T 's base type (there is an implicit conversion child -> base, so that's ok), and we are able to use fields in our generated methods.

Here is a complete code (see ServiceClient , Helpers.XLambdaExpression , Helper.EmitHelper ).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM