2013-05-26 3 views
0

J'essaie de créer une méthode réutilisable pour une exécution d'événement plus complexe. Je ne peux pas l'obtenir pour compiler ou exécuter avec des événements de cadre qui ne suivent pas le modèle EventHandler<Type>. Je voudrais éviter la réflexion si possible car ce sera un événement très utilisé.Soulever un événement via une méthode générale

J'ai créé une application console de test ci-dessous qui illustre le problème:

using System; 
using System.Collections.Specialized; 

namespace CallEventsViaMethod 
{ 
    public class TestEventArgs : EventArgs { } 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      MyProgram program = new MyProgram(); 
      program.Go(); 
      Console.ReadKey(false); 
     } 
    } 

    public class MyProgram 
    { 
     public event EventHandler<TestEventArgs> TestEvent; 
     public event NotifyCollectionChangedEventHandler CollectionChangedEvent; 

     public void Go() 
     { 
      TestEvent += new EventHandler<TestEventArgs>(MyProgram_TestEvent); 
      CollectionChangedEvent += new NotifyCollectionChangedEventHandler(MyProgram_CollectionChangedEvent); 

      // Want a reusable method I can use to conditionally execute any event 
      GeneralEventExecutor.Execute<TestEventArgs>(TestEvent, new Object(), new TestEventArgs()); 
      GeneralEventExecutor.Execute<NotifyCollectionChangedEventArgs>(TestEvent, new Object(), new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); 
     } 

     void MyProgram_TestEvent(object arg1, TestEventArgs arg2) 
     { 
      Console.WriteLine("Custom event ran"); 
     } 

     void MyProgram_CollectionChangedEvent(object sender, NotifyCollectionChangedEventArgs e) 
     { 
      Console.WriteLine("NotifyCollectionChangedEventHandler event ran"); 
     } 
    } 

    public static class GeneralEventExecutor 
    { 
     public static void Execute<T>(EventHandler<T> eventToRaise, object sender, T eventArgs) where T : EventArgs 
     { 
      if (eventToRaise == null) 
       return; 

      Delegate[] registeredEventHandlers = eventToRaise.GetInvocationList(); 

      foreach (EventHandler<T> eventHandler in registeredEventHandlers) 
      { 
       object target = eventHandler.Target; // Need access to the Target property 

       // * Code deciding if should invoke the event handler * 

       eventHandler.Invoke(sender, eventArgs); 
      } 
     } 
    } 
} 

Les messages d'erreur sont:

erreur CS1502: Le match de la meilleure méthode surchargée pour « CallEventsViaMethod.GeneralEventExecutor. Execute (System.EventHandler, objet , System.Collections.Specialized.NotifyCollectionChangedEventArgs) 'a certains arguments non valides

erreur CS1503: Argument 1: ne peut pas convertir « System.EventHandler » à « System.EventHandler »

Je comprends pourquoi je reçois l'erreur, mais ne peut pas trouver un moyen tour il.

+0

N'êtes-vous pas reinveinting l'événement Aggregator? –

+0

Ce que la méthode Execute fait dans mon code de production est soit Invoquant l'événement normalement, soit l'invoquant via dispatcher, j'essayais juste de garder le code simple. Je ne pense pas que l'Event Aggregator suffise dans ce cas? – Lee

+0

On dirait qu'il ne peut pas faire sans réflexion: http://stackoverflow.com/questions/8407886/pass-event-as-parameter-to-a-method – Lee

Répondre

0

Remplacez votre votre Execute<T> générique ci-dessous

public static void Execute<T>(Delegate eventToRaise, object sender, T eventArgs) where T:EventArgs 
     { 
      if (eventToRaise == null) 
       return; 

      Delegate[] registeredEventHandlers = eventToRaise.GetInvocationList(); 

      foreach (Delegate eventHandler in registeredEventHandlers) 
      { 
       object target = eventHandler.Target; // Need access to the Target property for conditions 

       // * Code deciding if should invoke the event handler * 

       eventHandler.DynamicInvoke(sender, eventArgs); 
      } 
     } 
+0

Obtenez une erreur à l'exécution sur la ligne eventHandler.Invoke ... "Delegate 'System.EventHandler ' a des arguments invalides" – Lee

+0

Vérifiez maintenant avec DynamicInvoke comme ci-dessus – Nair

+0

Ne comprenez pas vraiment pourquoi, mais je reçois: L'objet de type 'System.Collections.Specialized.NotifyCollectionChangedEventArgs' ne peut pas être converti en type 'CallEventsViaMethod.TestEventArgs'. – Lee

Questions connexes