C#最佳实践 - 活动订阅

时间:2011-02-28 02:56:14

标签: c# events

非常基本的问题,所以我只是在寻找最佳实践。

我的班级有一些应该订阅的活动。 (例如DiscoveryCompleted)。在方法中我会检查事件是否为null,但是我不确定是否应该引发异常,如果是,那么是什么类型。 NotImpletementedException?

如果异常未处理,则看起来不太优雅。

你的想法?

5 个答案:

答案 0 :(得分:3)

我的想法是这正是为NotImplementedException创建的。您永远不应该在生产代码中遇到NotImplementedException,但是在测试期间,您可以清楚地看到您的代码路径已经完成了。

有点像TODO的评论,但更多的是在你面前:)

虽然,我可能会质疑是否有一个必须订阅的事件处理程序,而没有默认订阅者,并不表示存在设计问题。

修改

根据您的评论,我认为我稍微误解了您的初始问题。正如其他人所说(并且我质疑),当你没有订阅事件处理程序时,你不应该抛出异常;根本就不要试着打电话。如果没有人关心事件x的发生,你就无法对此做任何事情。

您的代码有责任关心是否有人关心它的发生,而只是告诉他们如果他们关心的话就会发生这种情况。

编辑2 - 现在有更多代码

public interface INeedToKnowAboutSomethingImportant 
{
    void WhenSomethingImportantHappens(SomethingImportantHappenedEventArgs args);
}


public class DoesSomethingImportant 
{
    private readonly INeedToKnowAboutSomethingImportant _needyDependency;
    public DoesSomethingImportant(INeedToKnowAboutSomethingImportant needyDependency)
    {
        _needyDependency = needyDependency;
    }

    protected void SomethingImportantHappened(object sender, EventArgs e)
    {
        //Handle internally
        _needyDependency.WhenSomethingImportantHappens(new SomethingImportantHappenedEventArgs(e));
    }
}

遵循此模式,您无需担心是否有人订阅了您的事件处理程序。你必须履行依赖关系,但是 AT ALL 你填的是什么并不重要,因为无论它是什么,它都会有你调用的方法。

答案 1 :(得分:2)

应该选择订阅活动。 如果您的类必须调用方法,请改为在其构造函数上传递委托。

答案 2 :(得分:1)

检查事件时,不应抛出NotImplementedException。只需检查,如果不为空则执行。

以p为例。您在页面上放置了一个元素,但您不打算在该按钮上实现任何事件。按钮检查Click事件,找不到,并抛出NotImplementedException。

现在这是错的。

事件是在某个程序被击中时引发的事情。然后你可以拥有由它“触发”的代码。无论事件是否存在,代码的主要路径都不应受到影响。如果在没有触发事件的情况下代码的主路径无法继续,则需要使用方法。

我的建议是: 1)创建一个事件。 2)使用稍后要实现的处理程序订阅事件。 3)在处理程序中抛出NotImplementedException。

至于异常是未处理的,你永远不应该处理NotImplementedException:P ...(你不应该为事件的null引用抛出NotImplementedException。)

答案 3 :(得分:0)

您不应该担心事件对象为空。如果没有人订阅该活动那么没有。如果您需要在事件引发类之外运行另一个函数,那么除了观察者模式之外,还需要使用另一种模式。正如Eduardo建议你可以传递一个委托,你也可以考虑一个构建模式。

答案 4 :(得分:0)

如果某个活动没有订阅者,我不会抛出。

在引发事件的“开启”方法中,您需要null test(注意比赛条件预防)。在其他地方,你的班级不应该认为该活动有订阅者。