Oct 23, 2009

A Better Event Idiom

I was watching a design pattern screencast over on DimeCast last night  (it was that or another rerun of That 70’s Show) when the author used an event handler. The code he typed used an older syntax and wasn’t thread safe. One of the standard Event patterns out there, has you copy the event first, then check the copy for null, then actually raise the event. That idiom makes sense, but it always struck me as ugly. And really what’s worse than an ugly idiom? Over a year ago, I came across a blog entry by Kristof Verbiest with a better way to do it. I’m only adding one item to the original blog and that is the use of the NonSerialized attribute. The [field: NonSerialized] attribute makes non serialized apply to the underlying delegate rather than the event itself. If this isn’t done any object that subscribes to our event has to get serialized along with our class and in every case I’ve come across that is not a desired behavior.

[field: NonSerialized]
public event EventHandler<TextEventArgs> TimerDisplayUpdate = (sender, eventArgs) => { };
private void RaiseTimerDisplayUpdate()
{
    TextEventArgs event_args = new TextEventArgs(_timerDisplay);
    TimerDisplayUpdate(this, event_args);
}
#endregion

The clever part I picked up from Kristof is adding the empty delegate. Now the EventHandler can never be empty. So you don’t need to check that it’s not null. If you don’t need to check it’s not null then it can’t become null between the time you check it and the time you use it, so now you don’t need to copy it before you check it.

You can also probably tell I don’t hold with the standard naming conventions for events. I’ve always found it very unintuitive and confusing. When I raise an Event I can’t see how it makes sense to call something with a prefix of On. So  when I want to raise an event it always starts with the word Raise, and on the other end when I want to handle an event, you guessed it, it starts with the word Handle. The only problem is the auto generated ones from VS don’t fit but I don’t find it that hard to rename them.

Here’s a ReSharper template you can cut and paste. I assign it the shortcut “event”.

[field: NonSerialized]
public event EventHandler<$EventArgs$> $EventName$ = (sender, eventArgs) => { };

void Raise$EventName$()
{
    $EventArgs$ event_args = new $EventArgs$($END$);
    $EventName$(this, event_args);     
}

About Me

My photo
Tod Gentille (@todgentille) is now a Curriculum Director for Pluralsight. He's been programming professionally since well before you were born and was a software consultant for most of his career. He's also a father, husband, drummer, and windsurfer. He wants to be a guitar player but he just hasn't got the chops for it.