The problem is that if nobody subscribes the the event, it is null. And you can’t invoke against a null. Three approaches leap to mind:
- check for null (see below)
- add a “do nothing” handler:
public event EventHandler MyEvent = delegate {};
- use an extension method (see below)
When checking for null, to be thread-safe, you must in theory capture the delegate reference first (in case it changes between the check and the invoke):
protected virtual void OnMyEvent() {
EventHandler handler = MyEvent;
if(handler != null) handler(this, EventArgs.Empty);
}
Extension methods have the unusual property that they are callable on null instances…
public static void SafeInvoke(this EventHandler handler, object sender)
{
if (handler != null) handler(sender, EventArgs.Empty);
}
public static void SafeInvoke<T>(this EventHandler<T> handler,
object sender, T args) where T : EventArgs
{
if (handler != null) handler(sender, args);
}
then you can call:
MyEvent.SafeInvoke(this);
and it is both null-safe (via the check) and thread-safe (by reading the reference once only).