2009-07-13 7 views
0

Dans ma classe 'myClass', j'utilise Reflection.Emit pour écrire dynamiquement un gestionnaire d'événements pour l'un des membres de la classe myClass.Référence 'this' dans le gestionnaire d'événements dynamiques

Je l'ai fait avec succès.

Maintenant, je veux modifier le gestionnaire d'événements pour appeler l'une des méthodes d'instance de la classe myClass.

Cependant, je ne peux pas comprendre comment pousser une référence à 'this' sur la pile MSIL en utilisant Reflection.Emit. Dans le gestionnaire d'événements, Ldarg_0 n'est pas une référence à 'this', mais plutôt le premier paramètre du gestionnaire d'événements.

Est-ce que quelqu'un sait comment pousser une référence à 'ceci' sur la pile pour que je puisse appeler une méthode d'instance. Par exemple, voici ce que je voudrais que le code C# pour ressembler à:

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

Merci!

+0

Lorsque vous dites "Main", faites-vous référence à une classe réelle ou à la méthode 'static void main' qui démarre un programme? Il semble qu'il y ait une certaine confusion basée sur la réponse de Jakers. – jasonh

+0

Désolé, mauvais choix. Je vais réviser – emrosenf

+0

Vous ne pouvez pas appeler une méthode d'instance à partir d'une méthode statique car il n'y a pas d'instance sur laquelle l'appeler. –

Répondre

3

Lorsque vous utilisez Reflection.Emit (et je présume DynamicMethod ici), vous pouvez choisir ce que le premier argument au code généré sera, et il peut être transmis implicitement par le délégué, comme celui-ci:

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

C'était la réponse parfaite! Merci beaucoup! – emrosenf

3

Si vous êtes dans main, alors il n'y a pas d'instance de votre classe Main. La fonction principale est statique.

+0

Désolé, pas ce que je voulais dire – emrosenf

Questions connexes