2009-07-13 45 views
18

我有這樣一段代碼不起作用:的addEventHandler使用反射

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

事件CardInserted存在於另一個DLL文件和對象「o」的載荷確定。委託處理程序的值有效。我只能解僱這個事件。

回答

25

這裏展示瞭如何附加一個事件使用反射的樣本:

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

我唯一關心的問題是`Func <>`委託不太適合事件。如果您有多個事件訂閱,則只有其中一個實際會產生返回值,這可能會導致應用程序的非確定性行爲。 – 2015-11-12 07:41:03

5

當你說這是行不通的......會發生什麼?沒有?例外?

思考:

  • 都事件和處理公衆?如果沒有,您需要通過合適的BindingFlags撥打電話GetEvent/GetMethod
  • 處理程序的簽名是否匹配?

這裏的工作示例(請注意我用一個靜態的處理程序,因此在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

我什麼也沒看到。什麼都沒發生。 – pedrofernandes 2009-07-13 20:45:18

18

下面是一個簡短但完整的例子工作:

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

現在,當你說「我只不能開火的事件」時,你究竟是什麼意思?您無意自己舉辦活動 - 活動發佈商需要這樣做。您實際提供給我們的所有代碼是否都適用?如果是這樣,它似乎沒有添加事件處理程序,這是問題。

您能否提供更多信息?