自定义流可以抛出自己的自定义异常,还是只抛出IOException?

时间:2013-02-08 22:45:12

标签: c# exception-handling stream

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

Connection发送/接收方法可能抛出像ServerClosedConnException或NetworkShutdownException之类的异常

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

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

4 个答案:

答案 0 :(得分:3)

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

如果您的Connection类正在抛出一个非常特殊的异常,例如ServerClosedConnExceptionNetworkShutdownException,那么您会抓住并重新抛出不太具体的 IOException,看看这是如何增加任何价值的。

答案 1 :(得分:2)

最佳做法是让异常冒泡,除非您有更多详细信息要添加,您可以自行处理异常。在第一种情况下,您抛出一个新的异常,其实际异常为InnerException

在MSDN中阅读Wrapping Exceptions

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

答案 2 :(得分:2)

Stream基类充当其子类的事实合约。如果您计划在公共API中公开您的子类,那么遵守Stream类的记录行为是值得考虑的,因为您的子类的用户可能幸福地不知道它的特定类型。例如,如果您希望遵守Read方法的合同,则您的实现不应暴露任何不属于http://msdn.microsoft.com/en-us/library/system.io.stream.read类型的异常。

但是,这并不意味着您不能使用更具体的异常类型。如果您有理由创建自定义异常类型(假设您在阅读了JerKimball提到的design guidelines之后认为这是一个好主意),它可能是IOException的子类。但是,除非使用异常详细信息进行日志记录,否则除非您的Stream子类的用户可能想要执行某些操作,否则这可能不是必需的。

答案 3 :(得分: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中,因为这是"形状"例外;但是如果我不同意这些指导方针并且按照自己的方式行事,它通常会在以后的路上咬我。 :)