为什么'公共事件EventHandler cccc'为空?
我有一个班级
public class Builder
{
public event EventHandler StartedWorking;
public Builder()
{
// Constructor does some stuff
}
public void Start()
{
StartedWorking(this, eventargobject); //StartedWorking is null --
}
}
这看起来很简单,我一直在做什么?我错过了一些明显的东西,或者是否有可能导致这种情况的东西?
编辑:
这是否意味着如果我在客户端类中触发未订阅的事件,我必须检查它是否为空?
EDIT-2:
我想我从未有过从未订阅的事件,因此从未遇到过 - 你每天学习新的东西 抱歉看似愚蠢的问题......
答案 0 :(得分:12)
除非有人订阅了该事件,否则事件处理程序将为null。一旦委托订阅了该事件,它就不再是空的。
这就是为什么总是建议使用以下表格来举起活动:
public void Start()
{
var handler = this.StartedWorking;
if (handler != null)
{
handler(this, eventArgObject);
}
}
如果没有订阅者,这可以保护您免受空异常。
答案 1 :(得分:2)
正如其他人已经说过的那样,它是空的,因为没有订阅者。
要回答您的编辑:是的,您应该在触发事件之前检查事件是否为null。但是,如果你只是做一个简单的if(StartedWorking != null){...}
,你就会面临竞争条件,因为订阅者可能会在空检查之后但在你触发事件之前取消订阅。因此,在检查null的事件时应始终使用此模式:
protected void OnStartedWorking()
{
EventHandler localEvent = StartedWorking
if(localEvent != null)
{
localEvent(this, EventArgs.Empty);
}
}
这可以通过首先获取事件的副本来防止竞争条件,从而在复制点修复订阅列表。
有关在MSDN上发布活动的更多信息:How to Publish Events that Conform to .NET Framework Guidelines
(这是因为.net中的MultiCastDelegate类在imutable中,因此任何更改事件上的订阅者列表的尝试都不会影响您所做的副本)
答案 2 :(得分:0)
如果您尚未将任何事件订阅者挂钩到您的StartedWorking事件,那么它将为null。这就是.NET事件的工作原理。
除其他事项外,This article表明在调用事件之前应检查null。 This other question and answer演示了如何以避免空检查的方式创建事件(基本上通过总是添加空处理程序)。
答案 3 :(得分:0)
您不需要分配功能吗?
StartedWorking += new EventHandler(afunction);
void afunction(object sender, EventArgs e)
{
DoSomething();
}