2011-02-28 70 views
1

非常基本的问题,所以我只是寻找最佳实践。C#最佳实践 - 事件订阅

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

如果异常未处理,它看起来不很优雅。

您的想法?

回答

3

我认为这正是NotImplementedException的创建目的。你绝对不应该在生产代码中遇到NotImplementedException,但是它在测试过程中会让你痛苦地清楚你的代码路径有没有被实现。

有点像一个TODO注释,但多在你面前:)

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

编辑

我想我误解了你最初的问题咯,根据您的评论。正如其他人所说(我质疑),当你没有一个事件处理程序的订阅者时,你不应该抛出异常;根本不要试图称呼它。如果没有人关心这个事件x发生,你不能对此做任何事情。

你的代码没有责任关心是否有人在意它发生了什么,而只是为了通知他们,如果他们照顾的话就发生了。

EDIT 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)); 
    } 
} 

按照这个模式,你不必担心是否有人订阅了事件处理程序。你必须完成依赖关系,但所有并不重要,因为无论它是什么,它都会有你要调用的方法。

+0

感谢您的意见。我最初的想法是,NotImplementedException可能意味着该方法执行的逻辑尚未实现(例如发现),并且可能不指向调用该方法的类(它应该订阅该事件) – Henno

+0

btw ..什么是你的意思是有一个默认的用户? – Henno

+0

我的意思是,如果你要在事件处理程序为空时抛出异常,那么你就是为了所有意图和目的而要求它被某物订阅。如果是这种情况,您应该至少创建一个最初订阅它的处理程序。如果处理程序列表以某种方式被清除,您仍然需要保留空处理,但是对于没有其他人实际上在乎处理程序激发的情况,应该使用默认值。 – arootbeer

2

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

+0

+1 - 好主意!您也可以将委托传递给相关的方法。 – TrueWill

+0

很简洁的答案。强制代码的用户在编译时在前端执行,而不是在运行时在后端执行。 – DanTheMan

0

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

0

如果事件没有订阅者,我不会抛出。

在引发事件的“On”方法中,您将需要一个null test(注意竞争条件预防)。在其他地方,你的班级不应该认为该活动有订户。

1

当你检查你的事件时,你不应该抛出NotImplementedException。只需检查,如果不为空则执行。例如:

。你在页面上放置一个元素,但你不打算在按钮上实现任何事件。按钮检查Click事件,没有找到它,并抛出NotImplementedException。

现在,这只是错误的。

事件是在程序被击中某个点时引发的。然后你可以拥有由它“触发”的代码。代码的主要路径不应受到事件是否存在的影响。如果没有触发事件,代码的主路径无法继续,那么您需要改用Method。

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

至于异常是未处理的,你永远不应该处理NotImplementedException无论如何:P ...(你不应该抛出NotImplementedException对事件的空引用)。