Reference 'this' in dynamic event handler

天涯浪子 提交于 2019-12-01 12:28:19

问题


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!


回答1:


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



回答2:


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



来源:https://stackoverflow.com/questions/1121060/reference-this-in-dynamic-event-handler

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!