Archive for the ‘Events’ Category

Custom Event Best Practices, and Why I am Ignoring Them

Thursday, February 19th, 2009

I’m a firm believer in best practices.? They provide invaluable guidance about solutions that have worked and failed in the past.? Following them provides other developers an easy cue to understanding your code.? Whenever I see code that ignores these best-practices, I tend to treat it with more suspicion than I would code that follows the established practices.? This is why I decided that I should probably talk about a “best practice” that I do not like, and have after following it for a long time, have decided to forego for my latest project.

According to Microsoft, when creating a delegate for an event, they advise you to follow the same EventHandler pattern the .NET framework uses.? This pattern required you to create an event delegate with a return type of void and two parameters – a “sender” parameter of type Object, and an “e” parameter which should either be of type “EventArgs” or derived from it.? I have even propagated this pattern when I talked about the potential for a .NET memory leak based on the way the framework handles event subscriptions.

So what exactly is my problem with this pattern?? It has worked well for so long, it seems kind of silly to revisit it now, but to be honest it suffers from one major flaw in my opinion.? Essentially I do not believe that the “sender” parameter should be of type object.? I believe that it should in fact be strongly-typed, just as you would strongly-type any other parameter in your application.

After working in C# for a long time, I have encountered 2 methods of dealing with the “sender” parameter in events.?

The first method is to ignore it.? When a developer creates a custom event, he or she includes all the needed information, including the strongly typed instance of the event sender, in the derived EventArgs class.? In the handlers, the developers simply ignore the sender as if it was not a useful piece of information, even though they are frequently accessing the sender via the EventArgs class.

The second method is the old cast and test method.? In this method, the developer knows that the object sending the event is interesting, and so the first thing he or she does is cast it to the expected type and test if the cast succeeded (or catch any casting exceptions depending on the method used to cast it).? Once they have a strongly-typed version of the sender, they can continue with handling the event appropriately.

Having encountered these patterns too many times, I have decided in my latest project to use a pattern which makes more sense to me.? In this case, that means that I have strongly-typed my “sender” parameter to the appropriate type.? This way I can use this information directly in any handlers I create, instead of having to create a custom EventArgs class that wraps information I should already have access to.

I have done some searching but have been unable to find any good reason for the generic sender pattern other than the fact that anyone can raise events, leading to the possibility of needing different types for the same event.? However, in my case, the benefits of having a strongly typed sender seem to outweigh the possibility of my wanting to use a different type to raise the event later.? So far it has worked far better than I had hoped and has allowed me to write event handlers that are more explicit in what they are accessing (at least to me).