views:

165

answers:

2

In my 'myClass' class, I am using Reflection.Emit to dynamically write an event handler for one of the myClass class' members.

I have done this successfully.

Now, I want to modify the event handler to call one of the instance methods in the myClass class.

However, I cannot figure out how to push a reference to 'this' onto the MSIL stack using Reflection.Emit. Within the event handler, Ldarg_0 is not a reference to 'this', but rather the first parameter of the event handler.

Does anyone know how to push a reference to 'this' on the stack so that I can call an instance method. For example, this is what I would want the c# code to look like:

public class myClass
{
private myObj1 obj1;
public myClass() {
   this.init();
}

private void init()
{
   obj1.myEvent += new myEvent_EventHandler(theHandler);
}

private void theHandler(myObj2 obj2, myObj3 obj3)
{
   // this is the part I'm having trouble with
   this.myFunction(obj2);
}

private void myFunction(myObj2 obj2)
{
   // irrelevant
}
}

Thanks!

+3  A: 

If you are in main, then there is no instance of your Main class. The main function is static.

Jake Pearson
Sorry, not what I meant
+2  A: 

When you use Reflection.Emit (and I'm presuming DynamicMethod here), you get to choose what the first argument to the generated code will be, and it can be passed implicitly by the delegate, like this:

using System;
using System.Reflection.Emit;

public class App
{
    static void Main()
    {
        DynamicMethod m = new DynamicMethod("test", typeof(void),
            new[] { typeof(App), // <-- type of first argument, your choice
                typeof(string) });

        var cg = m.GetILGenerator();

        cg.Emit(OpCodes.Ldarg_0);
        cg.Emit(OpCodes.Ldarg_1);
        cg.EmitCall(OpCodes.Call,
            typeof(App).GetMethod("ShowString"), null);

        cg.Emit(OpCodes.Ret);

        Action<string> d = (Action<string>) 
            m.CreateDelegate(typeof(Action<string>), 
            new App()); // <-- this is the first argument, *your* choice

        MyEvent += d;

        // Trigger event
        MyEvent("Hello there");
    }

    static event Action<string> MyEvent;

    public void ShowString(string s)
    {
        Console.WriteLine(s);
    }
}
Barry Kelly
This was the perfect answer! Thank you so much!