jeudi 3 janvier 2019

Howto compile a lamda expression into a dynamically created class.

I'm trying to create an extension of a class using reflection emit.

And it is kinda working.

var extendwith = new List<Type>();
extendwith.Add(typeof(object));
var t = Utils.DynamicInherit<BaseTest>("Extended",typeof(UtilsTest).GetMethod(nameof(Testing)), extendwith);

var instance = Activator.CreateInstance(t, new TestClass(), new { A=1 });


public class BaseTest
{
    public readonly TestClass testClass;

    public object IsNotNull;

    public BaseTest(TestClass testClass)
    {
        this.testClass = testClass;
    }
}

public static void Testing(BaseTest baseTest, List<object> objects)
    {
        foreach(var t in objects)
        {
            baseTest.IsNotNull = t;
        }
    }

What is happening here is that the the type (t) returned from the DynamicInherit method will now inherit from the BaseTest class and have a constructor containing 2 parameters (TestClass, Object)

The static method Testing will be called inside the constructor of the "constructed type". It is called using this IL code.

constructorBuilder.Emit(OpCodes.Ldarg_0); //The this a referance to the created base class
constructorBuilder.Emit(OpCodes.Ldloc_0); //Reference to a List<Objects> that is passed in thorugh the constructor
constructorBuilder.Emit(OpCodes.Call, constructor); //The function to be called.. in this case the "public static void Testing(BaseTest baseTest, List<object> objects)"

This is working "as expected", but I would like to change it to using a lamda expression instead of the static function..

var t = Utils.DynamicInherit<BaseTest>("Extended",(baseO, objects) => {foreach(var t in objects)
        {
            baseTest.IsNotNull = t;
        }} , 
        extendwith);

I know I have to change the line

constructorBuilder.Emit(OpCodes.Call, constructor); 

But I'm not able to figure out how.... Any suggestions???





Aucun commentaire:

Enregistrer un commentaire