Is there any reason to assign an event to a local variable before raising it?

I often see code like the following, and wonder if there is any reason for using a local variable for the event, instead of just using the event itself. Is there?

var handler = OnQueryComplete;
if (handler != null)
    handler(this, new RepositoryEventArgs<T>(results));
Jon Skeet
people
quotationmark

Yes, absolutely - it makes the nullity check safe.

If you just have:

// Bad code, do not use
if (OnQueryComplete != null)
{
    OnQueryComplete(this, ...);
}

then the last subscriber may unsubscribe between the check and the invocation, causing a NullReferenceException.

There are lots of options here:

  • Decide that you don't care about thread safety, even to the extent of it throwing an exception. (In many cases this may be reasonable, particularly if this is all your own codebase.)
  • Use an extension method to make this simple to achieve so the nullity check goes away anyway.
  • In C# 6, use the conditional null operator:

    OnQueryComplete?.Invoke(this, ...);
    
  • Set up the event with a single empty handler which is never removed:

    public event FooEventHander OnQueryComplete = delegate {};
    

You may also want to use Interlocked to make sure you've got the most recent value of the variable, to avoid memory model issues. See my blog post (including comments) for more discussion of this.

people

See more on this question at Stackoverflow