2009-07-13 9 views
0

In meiner Klasse 'myClass' verwende ich Reflection.Emit, um einen Ereignishandler für einen Member der myClass-Klasse dynamisch zu schreiben.Referenz 'this' im dynamischen Ereignishandler

Ich habe das erfolgreich gemacht.

Jetzt möchte ich den Event-Handler ändern, um eine der Instanzmethoden in der myClass-Klasse aufzurufen.

Allerdings kann ich nicht herausfinden, wie man eine Referenz auf 'this' mit Reflection.Emit auf den MSIL-Stack verschiebt. Ldarg_0 ist im Event-Handler kein Verweis auf 'this', sondern der erste Parameter des Event-Handlers.

Kann jemand einen Verweis auf "dieses" auf dem Stapel schieben, damit ich eine Instanzmethode aufrufen kann. Zum Beispiel möchte ich, dass der C# -Code wie folgt aussieht:

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

Vielen Dank!

+0

Wenn Sie "Main" sagen, beziehen Sie sich auf eine tatsächliche Klasse oder die 'static void main' Methode, die ein Programm startet? Es sieht so aus, als gäbe es einige Verwirrung aufgrund der Antwort von Jakers. – jasonh

+0

Sorry, schlechte Wahl. Ich überarbeiten – emrosenf

+0

Sie können eine Instanzmethode nicht von einer statischen Methode aufrufen, da es keine Instanz gibt, auf die sie aufgerufen werden kann. –

Antwort

3

Wenn Sie Reflection.Emit verwenden (und ich bin Vermutung DynamicMethod hier), Sie erhalten zu entscheiden, was das erste Argument für den generierten Code werden, und es kann von den Delegierten implizit übergeben werden, wie folgt aus:

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

Das war die perfekte Antwort! Ich danke dir sehr! – emrosenf

3

Wenn Sie in main sind, dann gibt es keine Instanz Ihrer Hauptklasse. Die Hauptfunktion ist statisch.

+0

Entschuldigung, nicht was ich meinte – emrosenf