I have a delegate object of type EventHandler<AsyncCompletedEventArgs> and I want to add this object to events of type EventHandler<T> where I know the type T always extends AsyncCompletedEventArgs. What I'm trying to do is kind of like this:
public static void AssignDelegate(this ICommunicationObject client, string eventName)
{
EventInfo eventInfo = client.GetType().GetEvent(eventName);
EventHandler<AsyncCompletedEventArgs> eventHandler = (object o, AsyncCompletedEventArgs e) =>
{
// Some generic code that will be used as a handler to all events
}
// I want be able to add the eventHandler to the eventInfo using the
// AddEventHandler method, but this does not seem possible since this
// event accepts delegates of type EventHandler<SomeClassThatExtendsAsyncCompletedEventArgs>
// (It probably would if the EventHandler generic argument was contravariant)
eventInfo.AddEventHander(client, eventHandler);
}
Is there other way to do this? Maybe changing at runtime the type of the parameter e
?
You can do it via reflection:
// your global handler, it can be regular method
private static void GlobalEventHandler(object o, AsyncCompletedEventArgs e)
{
Console.WriteLine(e.GetType());
}
// your extension method
public static void AssignDelegate(this object client, string eventName)
{
// get event
EventInfo eventInfo = client.GetType().GetEvent(eventName);
// get build handler method
MethodInfo buildHandlerMethod = MethodInfo.GetCurrentMethod().DeclaringType.GetMethod("BuildHandler");
// get type of arg;
// eventInfo.EventHandlerType is EventHandler<T>, where T: AsyncCompletedEventArgs,
// so we are interested in T
Type argType = eventInfo.EventHandlerType.GetGenericArguments()[0];
// add handler
eventInfo.AddEventHandler(client, (Delegate)buildHandlerMethod.MakeGenericMethod(argType).Invoke(null, null));
}
// method which returns proper handler for event,
// it delegates invocation to GlobalEventHandler
public static EventHandler<T> BuildHandler<T>() where T : AsyncCompletedEventArgs
{
return GlobalEventHandler;
}