tags:

views:

5718

answers:

9

It's known that you should declare events that take as parameters (object sender, EventArgs args). Why?

+11  A: 

This allows the consuming developer the ability to write a single event handler for multiple events, regardless of sender or event.

Edit: Why would you need a different pattern? You can inherit EventArgs to provide any amount of data, and changing the pattern is only going to serve to confuse and frustrate any developer that is forced to consume this new pattern.

Greg Hurlman
I usually just pass whatever I need in the handler. If I need an event with no information, I declare it void. If I need to give the event 1 specific object, I pass that alone. It's not that I have a different pattern, I'm just not sure of the necessity of a pattern (outside framework code).
ripper234
You pass what *you* need, but that's needlessly inflexible, and breaking an established best-practice without any gain in function.
Greg Hurlman
+1 greg, bad arch to couple your observers
DevelopingChris
The need to derive from EventArgs is causing me a problem. The class that I want to use as TEventArgs is a DataContract and I cannot inherit from EventArgs in that case because EventArgs doesn't have a DataContract. Great pattern!
wizlb
So create a DCEventArgs class that inherits from EventArgs and has a dependency on your custom DC class.
Greg Hurlman
I wrote a class a while back for testing purposes that sinks a handler on every event on an object, and logs those events. However, it requires that all handlers take the (object sender, EventArgs e) signature, otherwise logging the parameters to the handler would be a LOT harder.
Flynn1179
+5  A: 

Because it's a good pattern for any callback mechanism, regardless of language. You want to know who sent the event (the sender) and data that is pertinent to the event (EventArgs).

Eric Z Beard
+1  A: 

It seemed that this was Microsoft's way to evolve the event model over time. It also seems that they are also allowing another way to do it with the "new" Action delegate and it's variations.

casademora
+2  A: 

It is a good pattern to use, that way what ever implements the event can find what was sending it.

Also overriding the EventArgs and passing data through them is the best method. The EventArgs are a base class. If you look at various controls that call events, they have overridden EventArgs which gives you more information about the event.

Even if you don't need the arguments to do the event, if you do not include them with the first run of the framework and want to add them later, you break all previous implementations, and have to re-write them. Plus if you a creating a framework and going to distribute that it becomes worse because everybody that uses your framework will need to refactor.

David Basarab
A: 

Actually this is debatable whether or not this is the best practice way to do events. There is the school of thought that as events are intended to decouple two segments of code, the fact that the event handler gets the sender, and has to know what type to cast the sender into in order to do anything with it.

+1  A: 

Using a single parameter, EventArgs, for the data passed by an event allows you to add data to your event in future versions of your software without breaking existing consumers. You simply add new members to an existing EventArgs-derived class, or create a derived class with the new members.

Otherwise consistency and the principle of least surprise justify using EventArgs for passing data.

As for sender, in some (but not all) cases it's useful to know what type sent the event. Using a type other than object for the sender argument is too restrictive: it would mean that other senders couldn't reuse the same event signature.

Joe
A: 

Chris Anderson says in the Framework Design Guidelines book:

[T]his is just about a pattern. By having event arguments packaged in a class you get better versioning semantics. By having a common pattern (sender, e) it is easily learned as the signature for all events.

There are situations mostly involving interop that would require deviation from this pattern.

fryguybob
A: 

Sometimes you would like to force all of your event consumers to use a particular event parameter, for example, a security event which passes a boolean parameter, true for good, false for bad. In this case you want your consumer to be painfully aware of the new parameter, i.e. you want your consumers to be coupled with that parameter. Take note, your consumers are still decoupled from your event firing class, but not from your event.

I suspect that this scenario applies to a large number of cases and in those cases the value of EventArgs is greatly reduced.

Dean
A: 

I recently wrote a blog post about the sender object and its many awesome uses, check it out at: http://jasonjano.wordpress.com/2010/02/25/return-to-sender/

Jason