добавить обработчик отражением, используя наследование EventArg - PullRequest
1 голос
/ 22 июля 2010

В .Net 4 этот код выполняется без ошибок

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

Как я могу сделать то же самое в отражении?

Ответы [ 3 ]

2 голосов
/ 22 июля 2010

Вы можете использовать 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 голосов
/ 22 июля 2010

Группы методов ковариантны, поэтому MyFunc может быть преобразован в EventHandler<CustomEventArgs>, но сами объекты делегата - нет, поэтому EventHandler<EventArgs> не может быть. Вы можете использовать Delegate.CreateDelegate для создания делегата произвольного типа.

var handler = new EventHandler<EventArgs>(ConnectResponseReceived);
myEvent.AddEventHandler(a, Delegate.CreateDelegate
    (myEvent.EventHandlerType, handler.Target, handler.Method));
0 голосов
/ 22 июля 2010

Чтобы получить событие:

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

Чтобы вызвать делегата, попробуйте:

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

(На самом деле не проверялось, дайте мне знать, если это работает! Кстати, ваш делегатвыше может работать, если вы измените его на EventHandler<CustomEventArgs>(ConnectResponseReceived), не уверен.)

...