是否有必要让某人在事件发生之前注册参加活动?

时间:2009-10-02 12:01:26

标签: c# events

这听起来很疯狂,但我在课堂上创建了一个活动,试图在没有任何人注册的情况下提升它。但是它会给出一个例外。在提出异常之前是否有必要让某人注册?如果是,那么有什么工作呢?

7 个答案:

答案 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 { };添加到最后。

现在,每次举起活动时都不需要写一堆垃圾。