写自定义异常类时应考虑哪些因素?

7
7个回答

10

需要问自己的问题:

  1. 谁会捕获它?如果没有人,那么你不需要自定义异常。
  2. 你将在哪里抛出它?是否有足够的上下文信息可用,或者您需要多次捕获和重新抛出异常,才能使最终捕获者使用异常?
  3. 为什么要抛出它?因为你捕捉到一个异常并需要附加额外信息吗?因为您遇到了一些数据中无法恢复的错误,并需要将详细信息传达回客户端代码?还是因为您喜欢“抛”东西?
  4. 什么是异常?不是什么导致它发生,而是从接收者的角度来看它是什么?他们可以修复并重试吗?他们应该永远不重试什么?他们应该通知用户吗?他们应该附加上下文信息然后重新抛出吗?什么决定您需要传递的信息,如果有的话......

原则:

  1. 不要浪费时间在永远不会被捕获的自定义异常上。
  2. 不要“重复”异常:每种自定义异常类型都应该有一个明确定义的情况,在该情况下可以和应该捕获; 不匹配的异常应该拆分成它们自己的自定义类型(而不是,例如,强制捕获器在单个catch()子句中构建条件逻辑)。
  3. 除非您有很好的理由,否则始终允许附加内部异常/来自先前捕获的异常的数据。失去上下文信息很少有帮助。

1

我有点极简主义,只有在调用代码必须显式地响应特定条件才会创建自定义异常。对于所有其他情况,我将使用最适合的 .NET 库异常。例如 ArgumentNullException,InvalidOperationException


1

当你需要以某种方式区分一个异常时。 就是这样。当然,你也可以创建一个异常类,它采用枚举来区分其原因。

当您想要传递异常的额外信息时,这很容易看出。传递该信息的唯一原因是如果您想要能够稍后获取该信息,因此您将想要知道类型,以便从该类型而不是其他类型中检索信息。

在C++和其他一些语言中,您还可以对异常进行typedef。这将允许类型区分,并可能将来转换为自定义类。


1

正如Wheelie所说,首先寻找适当的框架异常,只有在真正需要捕获它们时才使用异常(特别是自定义异常)。

我使用一个包含UserMessage属性的自定义异常类,这样我可以在可能的情况下以普通语言向用户传播问题。

如果您正在使用.NET,请查看设计自定义异常。有趣的是,文档已经更改了其建议关于使用ApplicationException:

如果您正在设计需要创建自己的异常的应用程序,则建议从Exception类派生自定义异常。最初认为自定义异常应该从ApplicationException类派生; 然而,在实践中发现这并没有增加显着价值。有关更多信息,请参阅处理异常的最佳实践。


1

1
Greg,我看了你的博客文章,认为你可以把最后一节复制到这里作为回应。虽然大多数回应往往不超过一个段落,但没有什么阻止你写更多:一些深入的回应比许多短的回应更有效。 - Shog9

1

我使用自定义异常的主要原因是封装多个提供程序:如果一个SqlException泄漏出SqlDataAccess层,而SocketException泄漏出NetworkDataAccess层,则调用代码会依赖于您的实现细节。最好将它们包装成DataAccessException或其他异常。


0

我认为简单的答案是“在没有现有异常充分表达异常情况时创建自定义异常。”

我还有第二条规则:“仅在您期望开发人员能够处理异常时才创建自定义异常。”如果您不认为异常是可恢复的条件,则创建新异常没有意义。在这种情况下,抛出InvalidOperationException更有效率。

编辑:最终撰写了一篇关于此主题的博客文章:http://blogs.msdn.com/jaredpar/archive/2008/10/20/custom-exceptions-when-should-you-create-them.aspx


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接