简体   繁体   English

在动态事件处理程序中引用“ this”

[英]Reference 'this' in dynamic event handler

In my 'myClass' class, I am using Reflection.Emit to dynamically write an event handler for one of the myClass class' members. 在我的“ myClass”类中,我使用Reflection.Emit为myClass类的成员之一动态编写事件处理程序。

I have done this successfully. 我已经成功地做到了。

Now, I want to modify the event handler to call one of the instance methods in the myClass class. 现在,我想修改事件处理程序以调用myClass类中的实例方法之一。

However, I cannot figure out how to push a reference to 'this' onto the MSIL stack using Reflection.Emit. 但是,我无法弄清楚如何使用Reflection.Emit将对“ this”的引用推送到MSIL堆栈上。 Within the event handler, Ldarg_0 is not a reference to 'this', but rather the first parameter of the event handler. 在事件处理程序中,Ldarg_0不是对“ this”的引用,而是事件处理程序的第一个参数。

Does anyone know how to push a reference to 'this' on the stack so that I can call an instance method. 有谁知道如何在堆栈上推送对“ this”的引用,以便我可以调用实例方法。 For example, this is what I would want the c# code to look like: 例如,这就是我希望C#代码看起来像的样子:

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! 谢谢!

If you are in main, then there is no instance of your Main class. 如果您在main中,则没有Main类的实例。 The main function is static. 主要功能是静态的。

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: 当您使用Reflection.Emit (并且我在这里假定DynamicMethod )时, 可以选择生成的代码的第一个参数是什么,并且可以由委托隐式传递它,如下所示:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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