tl;dr: Why are field-like events implemented as a single delegate field? Wouldn't it be more straight-forward to use a list of delegates, thereby eliminating the
null special case and avoiding all the MulticastDelegate magic?
The usual pattern to raise field-like events (ignoring synchronization issues for the moment) is
if (MyEvent != null) MyEvent(this, e);
which can be quite confusing (Why do I have a null check for 0 handlers, but no loop for multiple handlers?), until you understand how field-like events are implemented and that
MyEvent refers to an automatic backing field which can contain either
null, a single delegate or a MulticastDelegate holding references to multiple handlers.
On a first glance, this seems to be a strange design choice. In particular, the obvious alternative would be to use a list of simple delegates, which is how the Observer pattern is commonly implemented in languages such as Java. True, the invocation would be slightly longer:
foreach (var handler in MyEvent) handler(this, e);
but it would be easier to understand (in my subjective opinion) and probably easier to implement (no need for all the delegate multicasting logic).
Obviously, the C# designers thought otherwise. Since they are a bunch of very smart people, there must have been a good reason for it. What is it?