0

我有自己的 Connection 类和 ConnectionStream 类,它基本上只是包装了 Connection 的发送/接收方法。

Connection 发送/接收方法可以抛出异常,如 ServerClosedConnException 或 NetworkShutdownException

我的 Stream 是否应该捕获这些并将它们包装在 IOException 中(使用 innerException),或者它可以让它们冒泡给用户(当然还有一些 try-finally 来处理清理)

我在 .NET 框架中看到,NetworkStream 将来自 Socket 的任何错误包装在 IOException 中

4

4 回答 4

3

除非您打算处理它们,否则不要捕获异常。它们将在调用堆栈中冒泡,直到上游处理程序捕获并处理它们,或者程序终止。

如果您的 Connection 类抛出了一个非常具体的异常,例如ServerClosedConnExceptionor NetworkShutdownException,而您抓住了它并重新抛出了一个不太具体 IOException的,我看不出它是如何增加任何价值的。

于 2013-02-08T22:59:10.523 回答
2

Stream 基类充当其子类的事实上的契约。如果您计划在公共 API 中公开您的子类,最好遵守 Stream 类的记录行为,因为您的子类的用户可能很高兴地不知道它的特定类型。例如,如果您希望遵守 Read 方法的约定,则您的实现不应公开任何不属于http://msdn.microsoft.com/en-us/library/中列出的类型的异常system.io.stream.read

但是,这并不意味着您不能使用更具体的异常类型。如果您有理由无论如何都要创建自定义异常类型(假设您在阅读 JerKimball 提到的设计指南后认为这是一个好主意),它可能是 IOException 的子类。但是,这可能不是必需的,除非您的 Stream 子类的用户除了记录异常详细信息之外可能还想做一些事情。

于 2013-02-08T23:14:26.290 回答
2

最好的做法是让异常冒泡,除非您有更多细节要添加,或者您可以自己处理异常。在第一种情况下,您抛出一个新异常,实际异常为InnerException.

阅读MSDN 中的包装异常

在你的情况下,我会让它冒泡。

于 2013-02-08T22:59:41.020 回答
1

以下是例外指南所说的:

[参考]

最相关的部分:

Do throw the most specific (the most derived) exception that is appropriate. 
For example, if a method receives a null (Nothing in Visual Basic) argument, 
it should throw System.ArgumentNullException instead of its base type 
System.ArgumentException.

我会推断这也意味着在您的情况下,最详细的例外是要传播的“正确”例外;对您的异常类型进行一些假设,它们可能是要传播的“正确”类型,可能包含在“ConnectionException”自定义异常中。

也就是说,我确实看到考虑将它包装在 中是“有意义的” IOException,因为这是异常的“形状”;但如果我不同意这些指导方针并且我按照自己的方式行事,它通常会在以后的路上咬我。:)

于 2013-02-08T22:55:25.353 回答