Tim Meyer
Tim Meyer

Reputation: 12600

Method which accepts both EventHandler<T> and EventHandler

Assuming you have a method like this

private void FireEvent<T>(EventHandler<T> eventHandler, T eventArgs, string name)
{
    var handler = eventHandler;
    if (handler != null)
    {
        Console.WriteLine(String.Format("Sending event {0}", name));
        handler(this, eventArgs);
    }
    else
    {
        throw new UnconnectedEventException(name);
    }
}

Is it possible to rewrite/overload/extend this method so it accepts both EventHandler<T> and EventHandler (eventArgs could e.g. be EventArgs.empty in the latter case)?

The current solution is this additional method:

private void FireEvent(EventHandler eventHandler, string name)
{
    var handler = eventHandler;
    if (handler != null)
    {
        Console.WriteLine(String.Format("Sending event {0}", name));
        handler(this, EventArgs.Empty);
    }
    else
    {
        throw new UnconnectedEventException(name);
    }
}

But this involves copying every line of the implementation with one minor difference, which kills me on the inside. There surely must be a better solution.

Note: The second example fires an EventHandler, not an EventHandler<EventArgs>. The two types cannot be converted to each other since they are unrelated delegates.

Upvotes: 1

Views: 97

Answers (1)

Jeroen Mostert
Jeroen Mostert

Reputation: 28789

I'd say the shortest correct solution that does not copy code or ignore EventArgs is:

private void FireEvent<T>(EventHandler<T> eventHandler, T eventArgs, string name)
{
    if (eventHandler == null) throw new UnconnectedEventException(name);
    Console.WriteLine(String.Format("Sending event {0}", name));
    eventHandler(this, eventArgs);
}

private void FireEvent(EventHandler eventHandler, EventArgs eventArgs, string name) =>
    FireEvent(eventHandler == null ? null : new EventHandler<EventArgs>(eventHandler), eventArgs, name);

(The standard pattern of first assigning the event handler to a local variable for thread safety is not necessary here, since we've already implicitly copied it as part of the method call.)

Upvotes: 3

Related Questions