刚读完Jon Skeet 关于事件和代表的文章并得到了一个问题.
让我们首先在代码中声明一个事件
public event EventHandler MyEvent
Run Code Online (Sandbox Code Playgroud)
然后我想以某种方式在代码中提出它
if (MyEvent != null)
Myevent(this,EvtArgs.Empty);
Run Code Online (Sandbox Code Playgroud)
Jon说,实际上MyEvent看起来像这样:
private EventHandler _myEvent;
public event EventHandler MyEvent
{
add
{
lock (this)
{
_myEvent += value;
}
}
remove
{
lock (this)
{
_myEvent -= value;
}
}
}
Run Code Online (Sandbox Code Playgroud)
问题是我比较时会发生什么MyEvent != null?正如我其实明白它比较_myEvent到null,但我不知道.
如果您实现自定义添加/删除访问器,您将无法首先MyEvent与null 进行比较,因为它只是一个事件 - 它没有这样的值,只添加/删除访问器.您必须使用您声明的字段(_myEvent在上面的示例中).
当您使用类似字段的事件时,您只能使用事件名称进行比较,最终(有效地)结束字段和具有相同名称的事件.(编译代码不具有的字段名实际重用事件名称,但它必须看起来就像当你正在编译它.)
请注意使用此:
if (MyEvent != null)
MyEvent(this,EvtArgs.Empty);
Run Code Online (Sandbox Code Playgroud)
不是线程安全的,因为在检查和调用之间MyEvent可能变为null .你应该使用:
EventHandler handler = MyEvent;
if (handler != null)
{
handler(this, EventArgs.Empty);
}
Run Code Online (Sandbox Code Playgroud)
另请注意,关于字段式事件锁定的部分this现在稍微过时了; 在C#4中,使用无锁比较交换机制实现线程安全.