以线程安全的方式引发事件(为了避免NullReferenceException
),需要在调用之前复制事件委托:
EventHandler copy = TheEvent;
if (copy != null)
copy(this, EventArgs.Empty);
或在C#6中使用空条件运算符和Volatile.Read
作为proposed by Jon Skeet:
Volatile.Read(ref TheEvent)?.Invoke(this, EventArgs.Empty);
(有关讨论,请参阅C# Events and Thread Safety。)
这很乏味且容易出错。向C#添加raise
关键字是否有意义,以便上述模式(或C#编译器团队选择的改进模式)将由编译器进行透明处理,例如
raise TheEvent(this, EventArgs.Empty);
与using
和async
/ await
一致,这将是一种语法上的便利,可以解决围绕以确定方式提出事件的正确方式的混淆。
有什么缺点?
修改
感谢大家的反馈 - 添加另一个关键字确实有点极端。
但是,由于仍然缺乏提升活动的“标准”方式,并且有许多人喜欢Raise()
扩展方法,因此我建议在Visual Studio UserVoice channel将其添加到mscorlib
。
答案 0 :(得分:2)
这真的容易出错或令人困惑吗?即使他们确实添加了这样的关键字,他们仍然必须保持提升事件兼容性的旧方法,并且您必须知道正确方式来引发事件。您可以创建类似以下内容的扩展方法来完成大部分工作:
public static void Raise(this EventHandler handler, object sender, EventArgs args)
{
if (handler != null)
{
handler(sender, args);
}
}
我宁愿看到编译器团队努力使不可能变为可能,而不是将我的代码库减少几行。