Microsoft's tutorial on events shows how to check an event
for null
before triggering it:
protected virtual void OnChanged(EventArgs e)
{
if (Changed != null)
{ // Potential Race-condition at this point!
Changed(this, e);
}
}
But this leaves open a race-condition, as detailed in Eric Lippert's blog, where he writes that events should be triggered via a local event to avoid a race-condition:
protected virtual void OnChanged(EventArgs e)
{
ChangedEventHandler temp = Changed; // Local copy of the EventHandler
if (temp != null)
{ // Race condition avoided by local variable.
temp(this, e);
}
}
While this works, it has confused many developers who get it wrong, and don't put it in the locally-scoped event.
Another solution, from DailyCoding is to always initialize your event to have one empty handler, so a null-check is never needed:
// Set with empty delegate, will never be null
public event ChangedEventHandler Changed = delegate { };
protected virtual void OnChanged(EventArgs e)
{
// Neither Null-check nor local variable is needed; just trigger the event.
Changed(this, e);
}
This one makes a lot of sense, and is pretty simple.
However, since I see this technique so rarely mentioned online, I think there must be a reason why.
Is there a downside to initializing an event with an empty delegate like this?
You will see an absolutely tiny performance hit, but there are problems in more advanced cases, for example serializing and deserializing the class could lead to you losing the fake event handler, and the lack of a null check then throwing an exception.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With