当前位置:  开发笔记 > 编程语言 > 正文

是否在"null"引用(即没有订阅者的事件)上调用扩展方法?

如何解决《是否在"null"引用(即没有订阅者的事件)上调用扩展方法?》经验,为你挑选了5个好方法。

邪恶还是不邪恶?

public static void Raise(this EventHandler handler, object sender, EventArgs args)
{
   if (handler != null)
   {
      handler(sender, args);
   }
}

// Usage:
MyButtonClicked.Raise(this, EventArgs.Empty);

// This works too! Evil?
EventHandler handler = null;
handler.Raise(this, EVentArgs.Empty);

请注意,由于扩展方法的性质,如果MyButtonClicked为null,MyButtonClicked.Raise将不会抛出NullReferenceException.(例如,没有MyButtonClicked事件的监听器).

邪恶与否?



1> Dan Goldstei..:

不是邪恶的.我希望事件默认以这种方式工作.有人可以解释为什么没有订阅者的事件是空的吗?


我同意没有订阅者的事件不应该为空.没有订阅者的事件是空的,这似乎相当愚蠢 - 当然他们可以用一些带有空订阅列表的可重用类来初始化它.唉,现在改变已经太晚了.

2> jonnii..:

您可以随时声明您的活动(不是我推荐的):

public event EventHandler OnClicked = delegate { };

这样,当你调用它们时,它们会分配给它们,所以它们不会抛出空指针异常.

您可以在C#3.0中删除委托关键字...



3> alvin..:

不要忘记使用[MethodImpl(MethodImplOptions.NoInlining)],否则可能是它不是线程安全的.

(很久以前就读过那个地方,记得它,谷歌搜索并发现http://blog.quantumbitdesigns.com/tag/events/)



4> Squirrel..:

来自java背景,这对我来说似乎总是很奇怪.我认为没有人听一个事件是完全有效的.特别是在动态添加和删除侦听器时.

对我来说,这似乎是C#的gottchas之一,当人们不知道/忘记每次检查null时会导致错误.

隐藏此实现细节似乎是一个很好的计划,因为它无助于每次检查空值的可读性.我确信如果没有人在监听,MSFT会说没有构建事件会有性能提升,但是在大多数业务代码中,无意义的空指针异常/可读性的降低远远超过了它.

我还将这两个方法添加到类中:

    public static void Raise(this EventHandler handler, object sender)
    {
        Raise(handler, sender, EventArgs.Empty);
    }

    public static void Raise(this EventHandler handler, object sender, TA args)
        where TA : EventArgs
    {
        if (handler != null)
        {
            handler(sender, args);
        }
    }



5> David..:

为什么会是邪恶的?

它的目的很明确:它引发了MyButtonClicked事件.

它确实增加了一个函数调用开销,但是在.NET中,无论如何它都会被优化掉或非常快.

这有点微不足道,但它解决了我对C#的最大抱怨.

总的来说,我认为这是一个奇妙的想法,并可能会偷走它.

推荐阅读
小妖694_807
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有