邪恶还是不邪恶?
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事件的监听器).
邪恶与否?
不是邪恶的.我希望事件默认以这种方式工作.有人可以解释为什么没有订阅者的事件是空的吗?
您可以随时声明您的活动(不是我推荐的):
public event EventHandlerOnClicked = delegate { };
这样,当你调用它们时,它们会分配给它们,所以它们不会抛出空指针异常.
您可以在C#3.0中删除委托关键字...
不要忘记使用[MethodImpl(MethodImplOptions.NoInlining)]
,否则可能是它不是线程安全的.
(很久以前就读过那个地方,记得它,谷歌搜索并发现http://blog.quantumbitdesigns.com/tag/events/)
来自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); } }
为什么会是邪恶的?
它的目的很明确:它引发了MyButtonClicked事件.
它确实增加了一个函数调用开销,但是在.NET中,无论如何它都会被优化掉或非常快.
这有点微不足道,但它解决了我对C#的最大抱怨.
总的来说,我认为这是一个奇妙的想法,并可能会偷走它.