2010-08-09 72 views
11

目前我正在编写一个客户类,它利用DNS,套接字和SSL以及其他喜欢抛出异常的类。其他人将实施这个类,所以我想知道抛出异常的最佳做法是什么。创建自定义异常或使用内置异常?

我应该创建自己的自定义异常,以便他们知道是我的类抛出异常,还是应该让我调用的类和方法(DNS,套接字等)抛出它们自己的异常?目前,代码数百行,并且随着许多不同的方法调用而增长。在这种情况下抛出异常的最佳做法是什么?

回答

20

如果BCL包含已经传达你想要的含义(ArgumentNullException,例如)类,使用这些。

使用您自己的异常类保留特定于您的API的事物。

如果你觉得你可以添加信息,通过各种手段提高自己的异常,但不吞例外 - 传播起来作为自己的内部异常。

+0

+1对于内部异常 – Arthur 2010-08-09 20:00:15

+1

如果您正在使用多个线程,请严重考虑AggregateException - 虽然这是.NET 4的本机特性,但它值得移植到.NET 3.5或更早版本。请参阅http://msdn.microsoft.com/en-us/library/system.aggregateexception.aspx – 2010-08-09 20:26:40

+1

我想补充一点,如果你的自定义异常是系统扩展的一个特例,但仍然足够具体以证明你自己创建,然后从该异常而不是从Exception中继承。 – 2010-08-09 22:23:32

6

这是好的,如果他们添加信息,但除非有一个安全问题不要咽下从底层服务的例外抛出自己的异常。

如果您正在捕捉一个异常并抛出一个新异常,请将旧异常分配给新异常的InnerException属性。您可以按照这种方式根据需要嵌套任意多个异常,从而为异常传播的方式创建分层“视图”,这对调试非常有帮助。

1

这确实取决于你的受众,即你的班级的消费者。例如,如果您本质上包装了许多不同的异常,则创建自定义异常可能是一个不错的主意,它可以简化消费者中的错误处理。

如果创建自定义异常,一定要包括原始异常到您的自定义异常的InnerException,除非你明确有充分的理由将其隐藏。这将使人们使用你的班级提供的最多信息,并且如果你的班级没有完全覆盖的例外返回,你将会覆盖你。

2

你可以做的最糟糕的事情是在消息字符串中抛出带有细节的ApplicationException。如果你发现自己需要这样做,那么就是自定义异常的时候了。

1

如果您希望任何人从您的异常中捕获和恢复,最好使用自定义异常类型的小型层次结构,可能按照预期的可恢复程度进行组织(例如,有意外事件发生的异常类型,但该套接字可能仍然是好的',另一个'套接字状态不能被信任,但从一个新的套接字连接开始可能工作',另一个'主机说你做什么不会工作,不要甚至烦恼重试,除非你有理由相信某些事情已经改变“)。引起例外的事件的细节往往不如被违反的后置条件的本质重要。