Reputation: 17377
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
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
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
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
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