Alex Rivera | Logout

In a C# event handler, why must the "sender" parameter be an object?

Asked 2009-09-17T09:24:12.733
77

According to Microsoft event naming guidelines, the sender parameter in a C# event handler "is always of type object, even if it is possible to use a more specific type".

This leads to lots of event handling code like:

RepeaterItem item = sender as RepeaterItem;
if (item != null) { /* Do some stuff */ }

Why does the convention advise against declaring an event handler with a more specific type?

MyType
{
    public event MyEventHander MyEvent;
}

...

delegate void MyEventHander(MyType sender, MyEventArgs e);

Am I missing a gotcha?

For posterity: I agree with the general sentiment in the answers that the convention is to use object (and to pass data via the EventArgs) even when it is possible to use a more specific type, and in real-world programming it is important to follow the convention.

Edit: bait for search: RSPEC-3906 rule "Event Handlers should have the correct signature"

Edit
Report

1 Answer

1

The pattern of using EventHandler(object sender, EventArgs e) is meant to provide for all events the means of identifying the event source (sender), and providing a container for all the event's specific payload. The advantage of this pattern is also that it allows to generate a number of different events using the same type of delegate.

As for the arguments of this default delegate... The advantage of having a single bag for all the state you want to pass along with the event is fairly obvious, especially if there are many elements in that state. Using object instead of a strong type allows to pass the event along, possibly to assemblies that do not have a reference to your type (in which case you may argue that they won't be able to use the sender anyway, but that's another story - they can still get the event).

In my own experience, I agree with Stephen Redd, very often the sender is not used. The only cases I've needed to identify the sender is in the case of UI handlers, with many controls sharing the same event handler (to avoid duplicating code). I depart from his position, however, in that I see no problem defining strongly typed delegates, and generating events with strongly typed signatures, in the case where I know that the handler will never care who the sender is (indeed, often it should not have any scope into that type), and I do not want the inconvenience of stuffing state into a bag (EventArg subclass or generic) and unpacking it. If I only have 1 or 2 elements in my state, I'm OK generating that signature. It's a matter of convenience for me: strong typing means the compiler keeps me on my toes, and it reduces the kind of branching like

Foo foo = sender as Foo;
if (foo !=null) { ... }

which does make the code look better :)

This being said, it is just my opinion. I've deviated often from the recommended pattern for events, and I have not suffered any for it. It is important to always be

answered 2009-09-17T11:08:08.733

Your Answer