这听起来很疯狂,但我在课堂上创建了一个活动,试图在没有任何人注册的情况下提升它。但是它会给出一个例外。在提出异常之前是否有必要让某人注册?如果是,那么有什么工作呢?
答案 0 :(得分:14)
是的,没有注册的事件为空。触发事件的标准方式是:
event EventHandler MyEvent;
private void FireMyEvent(EventArgs e) {
var handler = MyEvent;
if (handler != null)
handler(this, e);
}
Eric Lippert写了一篇很棒的article,说明为什么这种模式是触发事件的“正确”方式
答案 1 :(得分:5)
是。如果没有订阅者,则该事件将为null,并且在调用它时将获得NullReferenceException。正如thecoop所说,正确的检查方式是,但有一个简单的“捷径”:
public event EventHandler Event = delegate {};
这会导致事件的默认订阅者不执行任何操作,因此如果有订阅者则不会抛出异常。执行此操作会产生轻微的性能开销,但它确实不需要检查空值。
答案 2 :(得分:3)
在.NET中,事件(默认情况下)作为多播委托处理。这意味着,在将第一个事件处理程序分配给事件之前,事件引用将计算为null
。
这导致了举办活动的典型方式:
public event EventHandler Event;
protected virtual void OnEvent(EventArgs e)
{
EventHandler @event = Event; // Copy immutable delegate for thread safety.
if(@event != null) // Check for null.
@event(e); // Raise event.
}
答案 3 :(得分:1)
检查是否为空。
if (Object.Event != null) Object.Event();
HTH 亚历
答案 4 :(得分:1)
如果没有人订阅该事件,则事件对象为null
。通常的做法是使用类似OnEvent
的方法(假设您的事件被称为MyEvent
):
public event EventHandler<MyEventArgs> MyEvent;
void OnMyEvent(MyEventArgs args) {
if(MyEvent != null) MyEvent(this, args);
}
当你必须举起活动时,你只需拨打OnMyEvent
方法。
答案 5 :(得分:1)
只是添加你也可以使用扩展方法。
public static void RaiseSafe<T>(this EventHandler<T> eventHandler, object sender, T args)
where T : EventArgs
{
if (eventHandler != null)
eventHandler(sender, args);
}
并像这样使用它:
MyEvent.RaiseSafe(this,new EventArgs());
答案 6 :(得分:0)
解决该问题的最简单方法是声明事件:
public event EventHandlerType MyEvent = delegate { };
换句话说,将= delegate { };
添加到最后。
现在,每次举起活动时都不需要写一堆垃圾。