繁体   English   中英

异常处理:用户定义的异常好处

[英]Exception handling: user defined exception benefits

我的异常处理技能是非常初级的,我总是很困惑我应该如何使用它们,而不是如何/语法。 我目前正在使用 C# (如果有不同的适用于它的话)。

我的问题是,在开发应用程序时创建自己的异常 class 有什么好处? 与抛出标准异常 class 异常相比。 基本上什么是应用程序中异常的健康实践。

或者,如果没有好处,那么就有坏处?

通过创建自己的异常,您通常可以为最终用户创建更有意义的消息(或更多应用程序特定类型的消息),同时仍然包装原始消息,以免丢失任何有用的信息。

Bill Wagner 有一本很棒的书,其中涵盖了关于何时应该或不应该创建自己的异常的一些推理,以及一般异常处理的一些良好实践。 这是一个小摘录:

您的应用程序会抛出异常——希望不会经常发生,但它会发生。 如果您不执行任何特定操作,只要您在核心框架上调用的方法出现问题,您的应用程序就会生成默认的 .NET 框架异常。 提供更详细的信息将使您和您的用户能够诊断并可能纠正现场错误。 当可以采取不同的纠正措施并且仅当可以采取不同的措施时,您才可以创建不同的异常类。 您可以通过提供基本异常 class 支持的所有构造函数来创建功能齐全的异常类。 您使用 InnerException 属性来携带由较低级别错误条件生成的所有错误信息。

如果您的应用程序存在特定类型的问题,需要在应用程序的更高级别上采用独特的恢复策略,您应该创建自己的异常类型,以便能够以最佳方式识别此类问题并从中恢复。

如果错误更多的是“调用者做错了什么”,请使用标准异常类。

如果您认为您的库将长期存在且有价值,那么我会错误地创建您自己的异常类,以便您的库的未来用户可以制定自己的恢复策略。

有时你想为不同类型的错误做不同的事情,例如,如果用户输入了错误的数据,它不会使整个应用程序崩溃,并且管理员 email。 对于更严重的异常(例如堆栈溢出),这样做是有意义的。 然后,您将根据错误类型实施不同的捕获。

如果一个方法被记录为在某些特定情况下抛出一些特定的 class 异常,它应该确保 class 的任何异常都不会在其他情况下通过它冒泡。 在许多情况下,确保这一点的最实用方法可能是创建自定义异常 class。

实际上,我认为大部分异常层次结构都非常无用,并建议关注相当少数的异常,几乎所有好的异常都应该从中派生。

  1. CleanFailureException - 由于某种原因无法执行指示的操作,但没有更改任何对象的 state。 没有理由相信任何对象的 state 已损坏,除非操作失败所暗示的程度。 如果 TrySomething 方法返回 False,这应该是 DoSomething 方法抛出的异常类型。 如果失败的操作使一个或多个对象处于部分更改或不一致的状态,则在某些情况下可能会包含在更严格的指令中。
  2. StateDisturbedException -- 由于某种原因,指示的操作无法完全执行,但可能已部分执行。 正在执行操作的 object 有一个 state 符合其自身的不变量,但可能符合也可能不符合调用者对它的期望。 只有在检查 object 并确保它符合预期(根据需要进行更改)后,调用者才可能尝试使用它。 或者,应该在目标 object 不再存在的地方捕获此异常,然后将其包装在 CleanFailureException 中。
  3. TargetStateCorruptException -- 指示的操作无法执行,因为正在执行的特定 object 已损坏,但没有特别的理由认为损坏会扩展到 object 之外。 这个异常应该在目标 object 不再存在的地方被捕获,然后用 CleanFailureException 包装和替换。
  4. ParentStateCorruptException - 指示的操作无法执行,因为某些 object 被目标文档视为“父”object 已损坏。 捕获损坏的父对象将不再存在的级别,然后包装在“CleanFailureException”中。
  5. SystemOnFireException

虽然有异常名称来指示错误的性质可能很好,但从捕捉的角度来看,重要的是是否可以安全地捕捉和恢复。 任何异常层次结构都应该关注后者,而不是前者。 of what went wrong, that should be done in Exception.Message.如果目标是通知出了什么问题,那应该在 Exception.Message 中完成。

主要好处是添加信息,因此异常更有意义,因此允许捕获特定于您的应用程序的异常。

抛出异常实际上是一个比悄悄失败更昂贵的操作,比如返回一个布尔值。 这个问题突出了我的意思:

异常比返回值贵多少?

如果您正在编写一些您预计其他开发人员将在他们自己的项目中使用的东西,那么可以肯定,异常可能对他们有用,以确保他们正确使用您的代码。 否则,如果您只是在自己的代码库中使用它,我会确保悄悄地失败。

自定义异常运行良好的一个示例是当您期望外部应用程序与您的项目交互时。

例如,如果您有一个发送 email 的小项目,如果您对必须通过电子邮件发送的最小收件人数量有硬性限制,那么抛出自定义“TooFewRecipients”错误可能是有意义的。

自定义异常通常会继承自 System.Exception

请记住,异常只能用于您的项目无法以任何其他方式处理的异常情况,并且它们应该易于理解以帮助第 3 方开发人员理解问题。 MSDN上有更多信息

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM