2010-07-22 64 views
1

添加處理程序在.NET 4中的代碼運行,並沒有錯誤通過反射使用EventArg繼承

class A 
{ 
    public event EventHandler<CustomEventArgs> MyEvent; 
} 

其中CustomEventArgs從EventArgs的

void Test() 
{ 
    A a = new A(); 
    a.MyEvent += MyFunc; 
} 
void MyFunc(object sender, EventArgs args) // EventArgs expect of CustomEventArgs 
{ 
} 

現在得到的,當我嘗試做反射一樣我得到不能施放代表例外

EvemtInfo myEvent = ... // get event somehow 
myEvent.AddEventHandler(a, new EventHandler<EventArgs>(ConnectResponseReceived)); 

我該如何在反射中做同樣的事情?

回答

2

您可以使用Delegate.CreateDelegate在這裏幫助:

using System; 
using System.Reflection; 

namespace ConsoleApplication13 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      A a = new A(); // the object *raising* the event 
      EventInfo evt = a.GetType().GetEvent("MyEvent"); 
      B b = new B(); // the object *handling* the event (or null for static) 
      MethodInfo handler = b.GetType().GetMethod("ConnectResponseReceived"); 
      Delegate del = Delegate.CreateDelegate(evt.EventHandlerType, b, handler); 
      evt.AddEventHandler(a, del); 
      a.OnMyEvent(); // test it 
     }  
    } 
    class A 
    { 
     public event EventHandler<CustomEventArgs> MyEvent; 
     public void OnMyEvent() { 
      var handler = MyEvent; 
      if(handler != null) handler(this, new CustomEventArgs()); 
     } 
    } 
    class B 
    { 
     public void ConnectResponseReceived(object sender, EventArgs args) 
     { 
      Console.WriteLine("got it"); 
     } 
    } 
    class CustomEventArgs : EventArgs { } 
} 
0

要獲取事件:

EventInfo myEvent = this.GetType().GetEvent("MyEvent") 

要調用的委託,請嘗試:

myEvent.AddEventHandler(a, new Delegate(this, "ConnectResponseReceived")); 

(沒有實際測試過它,讓我知道,如果它順便說一句,你的委託上述可能的工作!如果將其更改爲EventHandler<CustomEventArgs>(ConnectResponseReceived),則不確定。)

0

方法組是協變的,所以MyFunc可以轉換爲EventHandler<CustomEventArgs>,但委託對象本身不是,所以n EventHandler<EventArgs>不能。您可以使用Delegate.CreateDelegate創建任意類型的委託。

var handler = new EventHandler<EventArgs>(ConnectResponseReceived); 
myEvent.AddEventHandler(a, Delegate.CreateDelegate 
    (myEvent.EventHandlerType, handler.Target, handler.Method));