这些规则是否完全定义何时抛出异常?

时间:2010-07-17 16:41:19

标签: exception

  1. 如果一个方法无法按照它所说的那样做(例如,如果SendEmail无法发送电子邮件),它应该抛出异常。我在博客中深入探讨了这个问题(可选阅读):Do your work, or throw an exception - example。似乎这个想法已经成为一种惯例,即使我没有在别处找到它。 “例外是针对特殊情况”是一个不同的准则,需要额外的准则“不要使用例外进行正常的流量控制”,并要求讨论什么是“例外”。 “做你的工作或抛出异常”与方法的责任一样明确(已经应该是明确的)。
  2. 所有方法,包括“尝试”方法(例如TrySendEmail),如果发生某些不可恢复的错误,应该总是抛出 - 这会对应用程序的其他功能产生负面影响,而不仅仅是正在尝试的功能,例如RamChipExplodedException。也就是说,即使“TrySendEmail”在技术上完成了名称所指示的内容(尝试发送电子邮件),如果RAM爆炸,它仍然应该抛出异常(如果它甚至可以做到......)你得到我的漂移)。
  3. “尝试”方法只能在特殊情况下使用。
  4. 这些始终是良好的指导方针(即规则中是否有例外(双关语!))?你能想到其他没有涉及的人吗?

    澄清一点,我不是要求更具体的经验法则来帮助遵循这些指导原则;我正在寻找其他指南。

3 个答案:

答案 0 :(得分:1)

对我来说,#1规则是:避免正常流程中的异常。调试时,请确保发出所有抛出的异常信号。这是您的代码按照您设计的方式工作的第一个迹象。

除非您违反设计合同,否则TryXXX不应抛出异常。因此,例如,如果您传入空指针作为电子邮件的文本,则TrySendMail()可能会抛出。 如果没有它们就无法获得“正常流量”异常,你需要TryXXX方法。因此,对于解析数据,它们是必不可少的,我不会推荐TryLogin函数。

“你的工作或投掷”是一个很好的起点,但我不会成为教条。如果你问IndexOf一个不存在的项目,我可以使用一个返回-1的集合。您可以与您的同事讨论您想要绘制线的位置并输入您的编码标准。

我还经常使用异常来标记我认为未使用的控制路径。例如,如果我被迫编写一个我认为不会被调用的GetHashCode函数,我会抛出它。

答案 1 :(得分:1)

高效且有效的异常处理策略的基本目标是一种方法,即在调用者不准备处理的情况下抛出异常,同时让调用者处理它所准备的事情,而不会产生抛出异常的开销。 / p>

由于函数在调用者期望方面不能透视,通常的模式是具有多个版本的例程,其中不同的调用者可能具有不同的期望。决定调用Dictionary.GetValue的人表示期望传入的密钥存在于字典中。相比之下,调用Dictionary.TryGetValue的人传达了一个期望,即密钥可能在字典中,也可能不在字典中 - 或者是合理预期的。但是,即使在这种情况下,调用者可能也不希望CPU着火。如果在处理TryGetValue时发生CpuCaughtFireException,则应该允许它向上传播调用堆栈。

答案 2 :(得分:0)

在我看来,你不应该对“异常”这个名称过于笼罩,究竟是什么,也不是特殊情况。

异常只是另一个流控制语句,允许控制流来快捷调用堆栈。

如果这是您需要的(即您希望立即调用方法无法有效处理该条件),请使用异常。否则,不要。