2010-05-10 26 views
0

La tâche consiste à créer des gestionnaires d'événements en cours d'exécution. J'ai besoin que la méthode one soit appelée avec une valeur de paramètre différente pour différents événements. Les événements et leur nombre ne sont connus que pendant l'exécution. J'essaie donc de générer des méthodes dynamiques, dont chacune sera affectée à un événement, mais en général, elles transmettent simplement une valeur à une méthode d'instance et l'appellent.Comment passer la valeur lors de l'abonnement à un événement et l'obtenir lorsque l'événement est déclenché (problèmes d'utilisation de DynamicMethod)

Ce serait bien si quelque chose de similaire pouvait être fait le plus facilement. Je veux dire passer une valeur à l'étape d'abonnement et l'obtenir lorsque l'événement est déclenché.

C'est ce que je suis en train de faire maintenant:

public class EventSource 
{ 
    public event EventHandler eventOne; 
    public event EventHandler eventTwO; 
    public event EventHandler eventThree; 
} 

public class EventListener 
{ 
    SubscribeForEvents() 
    { 
     BindingFlags flags = 
        BindingFlags.IgnoreCase | 
        BindingFlags.Public | 
        BindingFlags.Instance; 

     // Suppose we've already got EventInfo 
     // and target source somewhere 
     // so we can do eventInfo.AddEventHandler(target, delegate) 
     // Now we need a delegate. 

     int value = 42; 
     Type tDelegate = eventInfo.EventHandlerType; 

     // http://msdn.microsoft.com/en-us/library/ms228976(VS.95).aspx 
     Type returnType = GetDelegateReturnType(tDelegate); 
     DynamicMethod listener = new DynamicMethod("", null, 
      GetDelegateParameterTypes(tDelegate), this.GetType()); 
     ///////// 

     Type[] callParameters = { typeof(int) }; 
     MethodInfo method = this.GetType().GetMethod("ToCallFromDelegate", flags); 
     ILGenerator generator = listener.GetILGenerator(); 

     // No success in this mess. What's wrong? 
     generator.Emit(OpCodes.Ldc_I4, value); 
     generator.Emit(OpCodes.Call, method); 
     generator.Emit(OpCodes.Pop); 
     generator.Emit(OpCodes.Ret); 
     ///////////// 

     Delegate delegate = listener.CreateDelegate(tDelegate); 
     eventInfo.AddEventHandler(target, delegate); 

     // When triggered, there is InvalidProgramException 
    } 

    void ToCallFromDelegate(int value) 
    { 
     doSomething(); 
    } 
} 

Répondre

0

lambdas comme gestionnaires d'événements;)