是调用一个“空”参考(即没有用户事件)的扩展方法邪恶?

邪恶还是不邪恶?

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 EventHandler<EventArgs> OnClicked = delegate { }; 

这样,当你调用它们时,他们有一些东西被分配给它们,所以它们不会抛出空指针exception。

你可能会摆脱C#3.0中的委托关键字…

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

(很久以前就读过,想起来,用googlesearch,发现http://blog.quantumbitdesigns.com/tag/events/

从java背景来看,这对我来说总是很古怪。 我认为没有人听一个事件是完全有效的。 尤其是当侦听器被dynamic添加和删除时。

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

隐藏这个实现细节似乎是一个很好的计划,因为它不会帮助每一次检查空值的可读性。 我确信MSFT会说如果没有人在监听,那么在没有构build事件的情况下性能会有所提高,但是在大多数业务代码中,无用的空指针exception/可读性下降会大大超过它。

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

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

为什么它会是邪恶的?

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

它确实增加了一个函数调用的开销,但是在.NET中,它将被优化或者非常快。

这是微不足道的,但它修复了我最大的抱怨与C#。

总的来说,我认为这是一个很好的想法,而且可能会偷走它。

我不会说这是邪恶的,但我很感兴趣的是你的扩展方法如何适应

 protected virtual OnSomeEvent(EventArgs e){ } 

模式以及它如何通过inheritance来处理可扩展性。 它是否假定所有的子类都会处理这个事件,而不是重写一个方法?

虽然我不会把它形容为邪恶的 ,但它仍然有一个负面的含义,因为它增加了不必要的开销:

打电话时

myEvent.Raise(this, new EventArgs());

对象EventArgs在所有情况下都被初始化,即使没有人订阅myEvent。

使用时

 if (myEvent!= null) { myEvent(this, new EventArgs()); } 

EventArgs只有在订阅了myEvent的情况下才被初始化。

在没有处理程序的情况下抛出exception是最不可取的。 如果没有处理程序,最好是空的而不是空的。