Ссылка this в обработчике динамических событий
В моем классе '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 ответа
Когда вы используете 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);
}
}
Если вы находитесь в main, то нет экземпляра вашего Main класса. Основная функция статическая.