这些规则是否完全定义了何时抛出异常? 如果某个方法无法执行它所说的操作(例如,sendmail无法发送电子邮件),它应该抛出异常。我在博客上写了这篇深度文章(可选阅读):。这一想法似乎已经成为一种惯例,尽管我还没有发现其他地方描述过它。“例外情况适用于例外情况”是一个不同的指南,要求额外的指南“不要将例外情况用于正常流量控制”,并要求讨论什么是“例外情况”。“执行您的工作或抛出异常”与方法的责任一样明确(应该已经明确) 所有方法,包括“Try”方法(例如,TrySendEmail),如果发生不可恢复的错误,则应始终抛出这些方法,这些错误会对应用程序的其他功能产生不利影响,而不仅仅是尝试的功能,例如RamChipExplodeException。也就是说,即使“TrySendEmail”在技术上实现了名称指示的功能(它尝试发送电子邮件),但如果RAM爆炸,它仍然应该抛出异常(如果它甚至可以这样做……你明白我的意思) 只有在特殊情况下才应使用“尝试”方法

这些规则是否完全定义了何时抛出异常? 如果某个方法无法执行它所说的操作(例如,sendmail无法发送电子邮件),它应该抛出异常。我在博客上写了这篇深度文章(可选阅读):。这一想法似乎已经成为一种惯例,尽管我还没有发现其他地方描述过它。“例外情况适用于例外情况”是一个不同的指南,要求额外的指南“不要将例外情况用于正常流量控制”,并要求讨论什么是“例外情况”。“执行您的工作或抛出异常”与方法的责任一样明确(应该已经明确) 所有方法,包括“Try”方法(例如,TrySendEmail),如果发生不可恢复的错误,则应始终抛出这些方法,这些错误会对应用程序的其他功能产生不利影响,而不仅仅是尝试的功能,例如RamChipExplodeException。也就是说,即使“TrySendEmail”在技术上实现了名称指示的功能(它尝试发送电子邮件),但如果RAM爆炸,它仍然应该抛出异常(如果它甚至可以这样做……你明白我的意思) 只有在特殊情况下才应使用“尝试”方法,exception,Exception,这些指导方针是否总是好的(例如,规则是否有例外(双关语!)?你能想到这些没有包括的其他人吗 澄清一下,我并不是要求更具体的经验法则来帮助遵循这些指导原则;我正在寻找更多的指导方针。在我看来,你不应该对“例外”这个名称以及什么是、什么不是例外情况挂断电话 异常只是另一个流控制语句,它允许控制流在调用堆栈上设置快捷方式 如果这正是您需要的(即,您希望立即调用方法不能有效地处理该条件),请使用异常。否则,不要这样做。对我来说,规则1是:在正常流程中避免异常。调试时,请确保所有抛出的异常都已发出信号。这

这些指导方针是否总是好的(例如,规则是否有例外(双关语!)?你能想到这些没有包括的其他人吗


澄清一下,我并不是要求更具体的经验法则来帮助遵循这些指导原则;我正在寻找更多的指导方针。

在我看来,你不应该对“例外”这个名称以及什么是、什么不是例外情况挂断电话

异常只是另一个流控制语句,它允许控制流在调用堆栈上设置快捷方式

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

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

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

“做你的工作或扔”是一个很好的起点,但我不会把它作为一个教条。如果你问
IndexOf
一个不存在的项目,我可以接受集合返回-1。你可以和你的同事们讨论你想在哪里划清界限,制定你的编码标准


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

高效和有效的异常处理策略的基本目标是为调用方不准备处理的情况抛出异常的方法,同时让调用方处理它准备好的事情,而不需要抛出异常的开销


由于函数不能洞察调用方的期望,通常的模式是有多个版本的例程,其中不同的调用方可能有不同的期望。决定调用Dictionary.GetValue的人表示希望传入的键存在于字典中。相比之下,调用Dictionary.TryGetValue的人传递了一种期望,即该键可能在字典中,也可能不在字典中——这两者都是合理期望的。然而,即使在这种情况下,调用方也可能不希望CPU着火。如果在TryGetValue的处理过程中发生CpuCaughtFireException,则应该允许它向上传播调用堆栈。

在不尝试定义的情况下要求定义有点像在水上扔鹅卵石。这些都是好的方面。我认为所有这些都符合上述规定。如果文档中说在这种情况下返回-1,那么即使对于未找到的项返回-1的IndexOf也会起作用。我认为
TryXX
方法如果由于调用方预期以外的任何原因失败,也会引发异常。如果在执行
TryGetValue
时,
字典
发现它已损坏(例如,通过同时访问两个线程),它不应该只返回false——它应该抛出一个异常,因为调用方将
false
返回解释为未添加密钥,或自上次添加后上次删除;如果结构已损坏,则这些语句可能不正确。@supercat:我同意。尝试不应该隐藏真正的问题。请考虑一下,我们不能总是猜测用户期望什么。考虑编写<代码> TryLogin <代码>:有些人可能认为当无法到达身份验证服务器时它会抛出。有些人可能期望它返回
false
。如果存在这种模糊性,则应记录行为,或者不应编写
TryXxx
API。@jdv JandeVaan:如果该方法应该从头开始创建连接,我将使用
ConnectAndTryLogin
TryConnectAndLogin
来区分调用方是否预期连接本身可能会失败。对于身份验证服务器,提供
CheckAuthenticationAvailability
方法。认证一般应能起作用;在确认可用后失败的情况非常罕见,因此可以使用
Try
/
Catch