当没有订阅者时,为什么委托为空而不是空列表?

时间:2009-11-02 03:02:15

标签: c# .net events delegates

有人可以解释为什么.Net框架团队决定没有订阅者的委托应该是null而不是具有空InvocationList的对象吗?我想知道导致这一决定的理由。

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

由于

4 个答案:

答案 0 :(得分:8)

在CLR级别,委托字段和事件字段是常规字段。

就像string MyField默认为null而非""一样,Action MyField默认为null而非Action实例。

答案 1 :(得分:2)

我同意这很麻烦,我个人认为这是一个错误。我想不出有什么理由可以这样做。

答案 2 :(得分:2)

请参阅Jon Skeet的回答here,以便对此进行讨论。甚至可以在C#2.0中检查null。

答案 3 :(得分:0)

使用null来处理空列表在运行时是有效的,特别是因为绝大多数事件都有零个或一个订阅者。 C#中的缺陷不是使用null来处理空列表,而是在许多上下文中事件名称引用委托而不是事件。更好的设计会使用前面的下划线或其他前缀命名委托,然后只允许使用事件名称的特定操作:

  1. 订阅
  2. 取消订阅
  3. 调用(如果非null则应调用_eventName,否则不执行任何操作)

对于所有其他事件操作,必须使用_eventName。与要求用户代码复制事件委托,测试是否为null,并且如果不是则调用副本相比,这样的设计可以节省数千(甚至数百万)代码行。