10

Can somebody explain why the .Net framework team decided that a delegate without subscribers should be null instead of an object with an empty InvocationList? I'd like to know the rationale that led to this decision.

void DoSomething()
{
    EventHandler handler = SomeEvent;
    if(handler != null)                   //why is this null-check necessary?
    {
        handler(this, EventArgs.Empty);
    }
}

Thanks

Matt Davis
  • 45,297
  • 16
  • 93
  • 124
Marcel Gosselin
  • 4,610
  • 2
  • 31
  • 54

4 Answers4

9

On the CLR level, delegate fields and event fields are regular field.

Just like string MyField defaults to null and not "", so too Action MyField defaults to null and not an empty Action instance.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
4

I agree that this can be cumbersome and I personally feel that this was a mistake. I cannot think of any reason why this has to be this way.

Andrew Hare
  • 344,730
  • 71
  • 640
  • 635
2

See Jon Skeet's answer here for a nice discussion of this. It is even possible to get around having to check against null in C# 2.0.

Community
  • 1
  • 1
Matt Davis
  • 45,297
  • 16
  • 93
  • 124
0

Using null to handle an empty list is efficient at run-time, especially since the vast majority of events have either zero or one subscribers. The defect in C# is not the use of null to handle an empty list, but rather the fact that in many contexts the event name refers to the delegate rather than the event. A better design would have named the delegate with a preceding underscore or other prefix, and then only allowed particular operations with the event name:

  1. Subscription
  2. Unsubscription
  3. Invocation (should invoke _eventName if non-null, else do nothing)

For all other event operations, one would have to use _eventName. Such a design would have saved countless thousands (if not millions) of lines of code, as compared with requiring user code to copy the event delegate, test if null, and invoke the copy if not.

supercat
  • 77,689
  • 9
  • 166
  • 211