views:

39

answers:

3

In .Net 4 this code run with no error

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

where CustomEventArgs derived from EventArgs

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

Now, when I try to do the same by reflection I get can't cast delegate exception

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

How can I do the same it in reflection?

A: 

To get the event:

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

To call the delegate, try:

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

(Not actually tested it, let me know if it works! BTW, your delegate above might work if you change it to EventHandler<CustomEventArgs>(ConnectResponseReceived), not sure.)

Lunivore
A: 

Method groups are covariant, so MyFunc can be converted to EventHandler<CustomEventArgs>, but the delegate objects themselves aren't, so an EventHandler<EventArgs> can't be. You can use Delegate.CreateDelegate to create a delegate of an arbitrary type.

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

You can use Delegate.CreateDelegate to help here:

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 { }
}
Marc Gravell