2009-07-13 5 views
18

ho questo pezzo di codice che non funziona:addEventHandler utilizzando la riflessione

public CartaoCidadao() 
{ 
    InitializeComponent(); 

    object o = WebDAV.Classes.SCWatcher.LoadAssembly(); 
    MethodInfo method = 
     this.GetType().GetMethod("Inserted", 
           BindingFlags.NonPublic | BindingFlags.Instance); 

    EventInfo eventInfo = o.GetType().GetEvent("CardInserted"); 
    Type type = eventInfo.EventHandlerType; 
    Delegate handler = Delegate.CreateDelegate(type, this , method); 

    eventInfo.AddEventHandler(o, handler); 
} 

void Inserted(string readerName, string cardName) 
{ 
    System.Windows.Forms.MessageBox.Show(readerName); 
} 

Il CardInserted evento esiste in un altro file DLL e l'oggetto "O" carichi OK. Il gestore delegato ha un valore dopo l'effetto. Non posso solo licenziare l'evento.

risposta

25

Ecco un esempio che mostra come collegare un evento utilizzando la riflessione:

class Program 
{ 
    static void Main(string[] args) 
    { 
     var p = new Program(); 
     var eventInfo = p.GetType().GetEvent("TestEvent"); 
     var methodInfo = p.GetType().GetMethod("TestMethod"); 
     Delegate handler = 
      Delegate.CreateDelegate(eventInfo.EventHandlerType, 
            p, 
            methodInfo); 
     eventInfo.AddEventHandler(p, handler); 

     p.Test(); 
    } 

    public event Func<string> TestEvent; 

    public string TestMethod() 
    { 
     return "Hello World"; 
    } 

    public void Test() 
    { 
     if (TestEvent != null) 
     { 
      Console.WriteLine(TestEvent()); 
     } 
    } 
} 
+3

Il mio unico problema con il codice è che un delegato 'Func <>' non è particolarmente adatto per gli eventi. Se si hanno più abbonamenti all'evento, solo uno di essi produrrà effettivamente il valore di ritorno, il che potrebbe comportare un comportamento non deterministico dell'applicazione. –

5

Quando si dice che non funziona ... cosa succede? Niente? Un'eccezione?

Pensieri:

  • sono sia l'evento e il pubblico del gestore? In caso contrario, sarà necessario passare il numero BindingFlags appropriato alle chiamate GetEvent/GetMethod.
  • corrisponde la firma del gestore?

Ecco un esempio di lavoro (nota che sto utilizzando un gestore statica, quindi il nulla in Delegate.CreateDelegate):

using System; 
using System.Reflection; 
class Test 
{ 
    public event EventHandler SomeEvent; 
    public void OnSomeEvent() 
    { 
     if (SomeEvent != null) SomeEvent(this, EventArgs.Empty); 
    } 
    static void Main() 
    { 
     Test obj = new Test(); 
     EventInfo evt = obj.GetType().GetEvent("SomeEvent"); 
     MethodInfo handler = typeof(Test) 
      .GetMethod("MyHandler"); 
     Delegate del = Delegate.CreateDelegate(
      evt.EventHandlerType, null, handler); 
     evt.AddEventHandler(obj, del); 

     obj.OnSomeEvent(); 
    } 

    public static void MyHandler(object sender, EventArgs args) 
    { 
     Console.WriteLine("hi"); 
    } 
} 
+0

Non vedo nulla. Non succede niente. – pedrofernandes

18

Ecco un esempio breve ma completo che fa lavoro:

using System; 
using System.Reflection; 

class EventPublisher 
{ 
    public event EventHandler TestEvent; 

    public void RaiseEvent() 
    { 
     TestEvent(this, EventArgs.Empty); 
    } 
} 

class Test 
{ 

    void HandleEvent(object sender, EventArgs e) 
    { 
     Console.WriteLine("HandleEvent called"); 
    } 

    static void Main() 
    { 
     // Find the handler method 
     Test test = new Test(); 
     EventPublisher publisher = new EventPublisher(); 
     MethodInfo method = typeof(Test).GetMethod 
      ("HandleEvent", BindingFlags.NonPublic | BindingFlags.Instance); 

     // Subscribe to the event 
     EventInfo eventInfo = typeof(EventPublisher).GetEvent("TestEvent"); 
     Type type = eventInfo.EventHandlerType; 
     Delegate handler = Delegate.CreateDelegate(type, test, method); 

     // Raise the event 
     eventInfo.AddEventHandler(publisher, handler); 
     publisher.RaiseEvent(); 
    } 
} 

Ora, quando dici "Non posso licenziare l'evento", cosa intendi esattamente? Non sei tenuto a essere in grado di generare eventi da solo: è compito dell'evento editore farlo. Funziona tutto il codice che ci hai presentato? Se è così, sembra che non stia aggiungendo il gestore di eventi che è il problema.

Potrebbe fornire ulteriori informazioni?