Вопрос по reflection.emit, cil, event-handling, c#, reflection – Ссылка 'this' в динамическом обработчике событий

0

В моем «myClass» класс, я использую Reflection.Emit для динамической записи обработчика события для одного из класса myClass & apos; члены.

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

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

Однако я не могу понять, как нажать на ссылку «это». в стек MSIL с помощью Reflection.Emit. В обработчике события Ldarg_0 является не ссылкой на «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
}
}

Спасибо!

Ничто здесь не статично, я написал пример кода emrosenf
Извините, плохой выбор. Я пересмотрю emrosenf
Когда вы говорите «Главное», имеете в виду реальный класс иstatic void main метод, который запускает программу? Похоже, что в ответе Джакерса есть некоторая путаница. jasonh
Вы не можете вызвать метод экземпляра из статического метода, так как нет экземпляра, чтобы вызвать его. Ed S.

Ваш Ответ

2   ответа
3

Когда ты используешь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);
    }
}
Это был идеальный ответ! Огромное спасибо emrosenf
3

то нет экземпляра вашего Main класса. Основная функция статическая.

Извините, не то, что я имел в виду emrosenf

Похожие вопросы