We all know the pattern to declare an event in C#, fairly easy, here is a remainder:

   1: public class EventTest
   2:         {
   3:             public event EventHandler MyEvent;
   4: 
   5:             public void RaiseEvent()
   6:             {
   7:                 if(MyEvent != null)
   8:                 {
   9:                     MyEvent(this, EventArgs.Empty);
  10:                 }
  11:             }
  12:         }

I know that many people forget to check that the event in not Null (meaning that someone has registered) before raising it and later on receive a well deserved exception :), and I know that many of you (including me) hate this pattern. Well, I am here to present you with a much more slick and usable pattern to declare events. In order to avoid that annoying Null check and make your code nicer, declare the event in the following way:

   1: public event EventHandler MyEvent = delegate {};

If you do it this way, you already have a delegate (an anonymous one) registered to the event and now, the event will never be null, so you can safely raise it without checking. Some would say that you are wasting resources but i think the Null check or an empty delegate are no big difference. The outcome is this much nicer class:

   1: public class EventTest
   2:         {
   3:             public event EventHandler MyEvent = delegate {};
   4: 
   5:             public void RaiseEvent()
   6:             {
   7:                 MyEvent(this, EventArgs.Empty);
   8:             }
   9:         }

About a week ago I wrote a post about why registering to events might cause your object not to get disposed. In this case the delegate belongs to the object being disposed , so both the object and his delegate loose the outside reference, hence, they will be disposed eventually.

Hope you like this idea as much as i did.

Amit

Tags :

14 Responses to “A New Pattern for Event Declaration”


  1. Kevin

    Said on March 26, 2008 :

    I’m assuming you read about this on Rob Eisenberg’s blog at http://devlicio.us/blogs/rob_eisenberg/archive/2008/03/20/net-event-techniques.aspx. If so, where’s the reference?

  2. Carlos Eduardo Appel Klein - DigitalDesk

    Said on March 26, 2008 :

    Nice approach.

  3. Admin

    Said on March 26, 2008 :

    Interesting, actually I did not read it anywhere,a friend at work showed it to my.
    maybe he did. I will ask him

  4. pedant

    Said on March 26, 2008 :

    ‘lose’.

  5. John

    Said on March 26, 2008 :

    Seems like this is happening a lot!
    http://www.mikeduncan.com/tech-post-ripoff/

  6. Ron

    Said on March 26, 2008 :

    Exactly my thoughts Kevin.

    And Amit I am sure your “friend” would have appreciated it if you had mentioned him/her at the first place.

  7. Admin

    Said on March 26, 2008 :

    Okay

    After doing some checking it appears that my friend, Michael Pavlovsky from http://blog.logrock.com/ read it at this blog. http://www.ayende.com/Blog/
    I looked around but could not find the article.
    But he claims it is there.

  8. Admin

    Said on March 26, 2008 :

    Just to set the record straight

    This is the post that everyone is talking about: http://devlicio.us/blogs/rob_eisenberg/archive/2008/03/20/net-event-techniques.aspx

    I admit it looks very much alike, but still, I did not rip him off. Sorry again if i offended anyone. Definitly not my attention.

    Amit

  9. Reza

    Said on April 10, 2008 :

    As far as I can remember the method responsible for raising the event should be protected & virtual. Why you may ask. Because the children of this class will be able to cancel the event.

    protected virtual void OnRaiseEvent();

    Note the ‘On’ in naming, its a convention.

  10. Simon

    Said on May 30, 2008 :

    It is worth noting that the first null-check pattern is also not thread-safe (though I think the second one is). The issue is that it is possible for the subscribing class to unregister for the event on one thread and for that to happen *after* the null-check but before the invocation, resulting in an unexpected null-reference exception.

    One common solution to this is to take a shallow copy of the event and check the *copy* for null-ness:

    EventHandler handler = MyEvent;
    if (handler != null)
    { handler (yada yada yada); }

    But the assign-empty-delegate pattern presented here also nicely solves this threading issue.

  11. Tresa

    Said on June 13, 2008 :

    Oh you saved a biiiig headache!!. I spend one whole afternoon and evening scratching my head over this .. Thanks a loooooot !

3 Trackback(s)

  1. Mar 28, 2008: igorbrejc.net » Friday Goodies - 28. March
  2. Apr 2, 2008: Blog Stats for March 2008 | Dev102.com
  3. Apr 18, 2008: dvilchez.net » Blog Archive » Algunos links

Post a Comment