2009-07-13 38 views
0

在我的'myClass'类中,我使用Reflection.Emit为myClass类的成员之一动态编写事件处理程序。在动态事件处理程序中引用'this'

我已经成功完成了这项工作。

现在,我想修改事件处理函数来调用myClass类中的一个实例方法。

但是,我无法弄清楚如何使用Reflection.Emit将引用'this'推送到MSIL堆栈。在事件处理程序中,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 
} 
} 

谢谢!

+0

当你说“主”是你指的是一个实际的类或启动程序的`static void main`方法吗?基于Jakers的回答,看起来有些混乱。 – jasonh 2009-07-13 18:07:40

+0

对不起,选择不好。我将修改 – emrosenf 2009-07-13 18:13:18

+0

您不能从静态方法调用实例方法,因为没有实例可以调用它。 – 2009-07-13 18:19:26

回答

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

如果你在main中,那么你的Main类没有实例。主要功能是静态的。

相关问题