3

以线程安全的方式(为了避免NullReferenceException)引发事件需要在调用之前复制事件委托:

EventHandler copy = TheEvent;
if (copy != null)
    copy(this, EventArgs.Empty);

或使用空条件运算符并在Jon Skeet 建议的Volatile.ReadC# 6 中:

Volatile.Read(ref TheEvent)?.Invoke(this, EventArgs.Empty);

(有关讨论,请参阅C# 事件和线程安全)。

这是乏味且容易出错的。向 C#添加关键字是否没有意义,raise以便编译器透明地处理上述模式(或 C# 编译器团队选择的改进模式),例如

raise TheEvent(this, EventArgs.Empty);

这将是一种符合usingand async/的语法便利await,可以解决围绕以最终方式引发事件的正确方式的困惑。

有什么缺点?

编辑

感谢大家的反馈 - 添加另一个关键字确实有点极端。

但是,由于仍然缺乏引发事件的“标准”方式,并且很多人喜欢Raise()扩展方法,我建议将其添加到mscorlibVisual Studio UserVoice 频道

4

1 回答 1

2

真的那么容易出错或令人困惑吗?即使他们确实添加了这样的关键字,他们仍然必须保留引发事件的旧方法以实现兼容性,并且您必须知道引发事件的正确方法。您可以创建如下扩展方法来完成大部分工作:

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

我宁愿看到编译器团队致力于使不可能成为可能,也不愿将我的代码库减少几行。

于 2013-03-23T21:24:46.640 回答