w.brian
w.brian

Reputation: 17377

Are there compelling reasons to use EventHandler<T> delegate instead of just Action<T> when declaring events?

When I declare an event, I've been using the Action delegate or Action<T, ...> delegate if the event handler has parameters. I recently noticed the existence of the EventHandler delegate, which requires a type param that inherits EventArgs. The latter method requires that I create an additional class that exists only to encapsulate whatever parameters are passed with the event, which seems unnecessary, unless I'm missing something.

So, what are the reasons for using the EventArgs delegate when declaring an event? What does it buy me?

Upvotes: 1

Views: 521

Answers (4)

supercat
supercat

Reputation: 81151

The biggest reason for using EventHandler<T> is probably that delegates of different types--even those types use the same method signature--are not interchangeable. If one event uses an EventHandler<fnordEventArgs> and another uses an Action<Object, fnordEventArgs>, the same methods could be subscribed to both events, but delegates created for one event could not be used with the other. Normally, this would be no big deal, since the statement like FirstEvent += methodName would translate into FirstEvent += new EventHandler<fnordEventArgs>(methodName), and SecondEvent += methodName would translate into FirstEvent += new Action<Object, fnordEventArgs>(methodName). In some cases, however, it is necessary for an event subscriber to store the delegate used to subscribe. For the subscriber to store the delegate, it must know its type--correctly. Consistently using EventHandler<T> as the delegate for event handling methods of the form void EventHandler(Object sender, T args) makes it must easier to create the right delegate type.

Upvotes: 1

SASS_Shooter
SASS_Shooter

Reputation: 2216

You indicated you use Action if arguments are needed. Comparing the two ask yourself what would be required if next year your requirements change and you need a new parameter passed in that event? Do you change lots of code or just one class that inherits EventArgs?

Upvotes: 1

Chris Shain
Chris Shain

Reputation: 51329

It provides you with an extensibility point for changing your event in the future.

Let's say I define a class Car:

public class Car { 
    String Make { get; set; }
    String Model { get; set; }
    int Year { get; set; }
}

and an event CarBuilt:

public event Action<Car> CarBuilt;

That's fine. But then, what if I want the event to later include the person who built the car? Using an action, I need to either change the event signature or add that information to the Car class (where it really doesnt belong).

If I define it this way instead:

public class CarBuiltEventArgs : EventArgs {
    public Car TheCar { get; set; }
}

public event EventHandler<CarBuiltEventArgs> CarBuilt;

Then I can add the BuiltBy property to the CarBuiltEventArgs class and I'm all set.

public class CarBuiltEventArgs : EventArgs {
    public Car TheCar { get; set; }
    public String BuiltBy { get; set; }
}

Upvotes: 2

Robert Harvey
Robert Harvey

Reputation: 180787

It buys you the ability to return event arguments, that's all. If you have no need for that, then maybe you don't need an EventHandler delegate.

From a larger perspective, EventArgs is the "socially acceptable" way of getting data from one place to another using events. You can create custom delegates to do this, of course, but EventArgs has tooling support in Visual Studio, etc.

Upvotes: 3

Related Questions