Skip to content

EventHandler Extension Method

February 7, 2009

I just wrote an interesting extension method, and thought I’d share it. If you’re using the EventHandler<T> delegate that was introduced back in .NET framework 2.0, this method might come in handy:

public static class ExtensionsForEventHandler
{
  public static void Raise<T>(this EventHandler<T> handler, object sender, T args)
    where T : EventArgs
  {
    EventHandler<T> evt = handler;
    if (evt != null) evt(sender, args);
  }
}

This helps you avoid having to repeat the boilerplate code that goes along with the typical event-firing pattern. With this extension method, you can do this instead:

public class StuffDoer
{
  public event EventHandler<StuffEventArgs> StuffHappened;

  public void DoStuff()
  {
    StuffHappened.Raise(this, new StuffEventArgs());
  }
}

Since extension methods can be called on references that are actually null, this will work even if no listeners have attached to the StuffHappened method.

I’m all about syntactic sugar, and extension methods provide an easy way to improve the readability of your code without too much hassle. (And you are writing your code so it’s easier for others to read, right? :)

About these ads

From → miscellaneous

13 Comments
  1. Jeremy Gray permalink

    No need for the extra evt variable, by the way, as the handler argument has a nice safe copy of the original handler anyway. As such, you can just do a null check on handler and then fire away!

  2. Gunnar Liljas permalink

    That’s a very nice use of extension methods, Nate! I will definitely use it!

    The evt variable should be somewhat useful for race condition handling.

  3. Jeremy Gray permalink

    re: “The evt variable should be somewhat useful for race condition handling.”

    No. As mentioned in my original comment the evt variable is unnecessary, even for “race condition handling”, as a point-in-time reference to the handler has already been correctly captured via the argument to the method.

  4. Gunnar Liljas permalink

    Duh! You’re of course perfectly correct! I didn’t see the context for all the goodies..:)

  5. Gunnar Liljas permalink

    Duh=Doh

  6. Nate – Great use of extension methods! I really like the readability of this. I’m trying to think of a way to do something similar to support INotifyProperty Change in Silverlight… should be interesting!

  7. In “Accelerated C# 2008″ it’s author shows a bit of code

    public class PlayerUI {
    public event EventHandler PlayEvent;
    protected virtual void OnPlay() {
    EventHandler localHandler = PlayEvent;
    if( localHandler != null ) {
    localHandler( this, new PlayEventArgs(“somefile.wav”) );
    }
    }
    }

    and then said, “In C#, you must test the event for null before calling it; otherwise, the result could be a NullReferenceException. The OnPlay method
    makes a local copy of the event before testing it for null. This avoids the race condition where the event is set to null from another thread after the null check passes and before the event is raised.”

    Could you please explain (or provide a link to explanations of) how exactly could event be set to null from another thread? Since making another localHandler reference to the same object in a code above (and copying an original reference to a handler variable internal to Raise() method in your code) helps to prevent race condition, I assume that another thread could re-assign initial global event reference to null, while a local copy of event reference stays good. But how exactly and why another thread does it?

    Thank you!

  8. I created something very similar to this in our codebase. I used to put a RaiseEvent method on each INotifyPropertyChanged implementor, but now I’ve got a set of handy extension methods for event raising.

  9. If your events are going to be fired very frequently this could affect performance. With your extension you create an instance of EventArg every time, whereas in the normal method of using an if(event == null) the EventArgs won’t be instantiated if no one is interested in the event.

    I’d be tempted to use it for readability sake, though needs documenting otherwise the next person to see it would probably put if (event == null) in front of it :)

  10. Ben, could you elaborate? Why did you say an instance of EventArgs is created every time? Isn’t it created only when Raise() method is actually called?

  11. Carlos Cubas permalink

    It seems I’m unable to raise an event defined on a base class.

Trackbacks & Pingbacks

  1. Dew Drop - Weekend Edition - February 7-8, 2009 | Alvin Ashcraft's Morning Dew
  2. .NET Quick Reminder #1 « CodeForNothing

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: