2009-07-13 14 views
18

Ich habe dieses Stück Code, das nicht funktioniert:addEventHandler mit Reflexion

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

Event CardInserted in einer anderen DLL-Datei und Objekt vorhanden ist "o" Lasten OK. Der Delegate-Handler hat einen Wert nach dem anderen. Ich kann das Ereignis nur nicht auslösen.

Antwort

25

Hier ist ein Beispiel dafür zeigt, wie ein Ereignis mit Reflexion befestigen:

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

Meine einzige Sorge mit dem Code ist, dass ein 'Func <>' Delegat nicht ganz gut für Ereignisse geeignet ist. Wenn Sie mehrere Abonnements für das Ereignis haben, wird nur einer von ihnen tatsächlich den Rückgabewert erzeugen, was zu einem nicht-deterministischen Verhalten der Anwendung führen kann. –

5

Wenn Sie sagen, dass es nicht funktioniert ... was passiert? Nichts? Eine Ausnahme?

Gedanken:

  • sind sowohl das Ereignis und die Handler Öffentlichkeit? Wenn nicht, müssen Sie geeignete BindingFlags an die GetEvent/GetMethod Anrufe übergeben.
  • stimmt die Signatur des Handlers überein?

Hier ist ein funktionierendes Beispiel (beachten Sie, ich bin einen statischen Handler, damit die Null 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

Ich sehe nichts. Nichts passiert. – pedrofernandes

18

Hier ist ein kurzes, aber vollständiges Beispiel der tut Arbeit:

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(); 
    } 
} 

Jetzt, wenn Sie sagen "Ich kann nur Ereignis nicht auslösen", was genau meinst du? Sie sind nicht dazu in der Lage, Ereignisse selbst zu veranstalten - es liegt beim Herausgeber der Veranstaltung, dies zu tun. Funktioniert der gesamte Code, den Sie uns tatsächlich präsentiert haben? Wenn dies der Fall ist, scheint es, dass der Ereignishandler nicht das Problem ist.

Können Sie mehr Informationen geben?