刚读完 Jon Skeet 的 article about events and delegates并提出一个问题。
让我们先在代码中声明一个事件
public event EventHandler MyEvent
然后我想通过某种方式在代码中提出来
if (MyEvent != null)
Myevent(this,EvtArgs.Empty);
Jon 说实际上 MyEvent 看起来像这样:
private EventHandler _myEvent;
public event EventHandler MyEvent
{
add
{
lock (this)
{
_myEvent += value;
}
}
remove
{
lock (this)
{
_myEvent -= value;
}
}
}
问题是当我比较 MyEvent != null
时到底发生了什么?
据我了解,实际上它将 _myEvent
与 null
进行了比较,但我不确定。
最佳答案
如果您实现自定义添加/删除访问器,您将无法首先将 MyEvent
与 null 进行比较,因为它仅是一个事件 -它没有这样的值(value),只有添加/删除访问器。您将不得不使用您的声明字段(上面示例中的_myEvent
)。
当您使用类似字段的事件时,您只能使用事件名称进行比较,在这种情况下您最终会(有效地)得到同名的字段和事件。 (编译后的代码不必实际重用字段名称的事件名称,但它必须看起来就像您编译时那样。)
注意使用这个:
if (MyEvent != null)
MyEvent(this,EvtArgs.Empty);
不是线程安全的,因为 MyEvent
在检查和调用之间 可能变为 null。你应该使用:
EventHandler handler = MyEvent;
if (handler != null)
{
handler(this, EventArgs.Empty);
}
另请注意,关于在 this
上锁定的类似字段的事件的部分现在有点过时了;在 C# 4 中,线程安全是使用无锁比较交换机制实现的。
关于c# - C#中事件的内部设计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9976200/