#389 – Check for Null Before Raising an Event
August 15, 2011 3 Comments
You should always check to see if an event is null, before trying to raise it.
if (Barked != null) Barked(this, new SomebodyBarkedEventArgs(Name, barkSound));
When no handlers are attached to the event, it will have a null value. If you try raising the event when it is null, you’ll get a NullReferenceException.
Alternatively, you could avoid having to check for null if you attach an empty handler to the event when you declare it.
public event EventHandler<SomebodyBarkedEventArgs> Barked = delegate { };
Nice website, I just found it today. One comment about checking for null before firing the event… The pattern that I have seen recommended is to do it like this:
public Bark(string barkSound)
{
var barked = Barked;
if (barked != null)
{
barked(this, new SomebodyBarkedEventArgs(Name, barkSound));
}
}
Saving the Barked value before checking for null and then invoking based on the saved value protects you on the off chance that Barked is set to null between the null check and the actual invocation.
Thanks Willie,
You’re right–you can make a copy, for full thread safety. In practice, this is likely pretty rare, just given that the timing would have to be just right. But this is good practice if/when you are writing code that is meant to be thread safe. Easy enough to know if your code might be raising an event on a different thread than the one that might unsubscribe to the event.
This is also likely rare for events on GUI-related objects, since event handlers are typically wired up once, at the start of the app, and then left attached. Again, if your code isn’t attaching/detaching handlers after startup, there’s no real need to implement this pattern.
Also note–if you do want to be thread-safe, you might consider the statement in my post where I attach an empty handler to the event when it is declared. This is probably a little cleaner than making a copy in the helper function, and guarantees that the event will never be null–so a nice alternative, for thread safety. Benefits–no need to check for null and no need to worry about race condition.
Pingback: #393 – Implement a Helper Method to Raise an Event « 2,000 Things You Should Know About C#