Ссылка 'this' в динамическом обработчике событий - PullRequest
0 голосов
/ 13 июля 2009

В моем классе 'myClass' я использую Reflection.Emit для динамической записи обработчика событий для одного из членов класса myClass.

Я сделал это успешно.

Теперь я хочу изменить обработчик событий для вызова одного из методов экземпляра в классе myClass.

Однако я не могу понять, как поместить ссылку на 'this' в стек MSIL с помощью Reflection.Emit. В обработчике событий Ldarg_0 - это не ссылка на this, а первый параметр обработчика событий.

Кто-нибудь знает, как поместить ссылку на 'this' в стек, чтобы я мог вызвать метод экземпляра. Например, я хотел бы, чтобы код 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
}
}

Спасибо!

Ответы [ 2 ]

3 голосов
/ 13 июля 2009

Когда вы используете 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);
    }
}
3 голосов
/ 13 июля 2009

Если вы находитесь в main, значит, нет экземпляра вашего Main класса. Основная функция статическая.

...