I'm trying to generate a type at run time via a TypeBuilder. I'm generating the instance methods of the type using a MethodBuilder, however I don't want to generate the il via IlGenerator.Emit
; instead I'd like to create an expression that represents the method, so can I convert it into an MethodBuilder for an instance method.
Is this possible? If so, how do I convert an Expression into a MethodBuilder instance method?
Quick Summary
Yes, you can, but you have to do some extra work. Jump down to the code snippet for the code to do so.
Long Answer
The Problem
Not directly, no. As noted in the SO Question: LambdaExpression CompileToMethod, while
LambdaExpression.CompileToMethod
in .NET 4.0 does take aMethodBuilder
, it can only represent a static method.A Partial Solution
So then, you need to work around this limitation by first creating a static method reference, and then create an instance method which calls that static method. If your expression does not have any "live objects" in it (i.e., you use an existing object reference when you were creating the Expression), then it's pretty straightforward to create a static method and then create an instance method that calls the static method. However, if you have a "live object" in your expression,
CompileToMethod
will inform you that it cannot use the Expression because you have a live object in your expression.A Full Solution
Instead of creating a static method, you can instead add a delegate field to your generated type, and then from your instance method, call the delegate field and forward the method arguments to the delegate.
CodeAssuming a
TypeBuilder
called_typeBuilder
, aMethodBuilder
calledmethodBuilder
, and a Delegate to forward to nameddelegateToInvoke
:When you create a new instance, be sure to set the field before using the instance: