异常引发

注释

此内容由 Pearson Education, Inc. 的许可从 框架设计指南:可重用 .NET 库的约定、习惯和模式(第 2 版)重新打印。 该版于2008年出版,此后该书已于 第三版全面修订。 此页上的一些信息可能已过期。

本部分中所述的异常引发准则要求对执行失败的含义有一个很好的定义。 每当成员无法完成其设计旨在做的事情(成员名称所暗示的内容)时,就会发生执行失败。 例如,如果 OpenFile 该方法无法向调用方返回打开的文件句柄,则被视为执行失败。

大多数开发人员已经习惯将异常用于使用错误(例如被零除或空引用)。 在 Framework 中,异常用于所有错误条件,包括执行错误。

❌ 请勿返回错误代码。

异常是在框架中报告错误的主要方法。

✔️ 请务必通过引发异常来报告执行失败。

✔️ 如果代码遇到进一步执行不安全的情况,请考虑通过调用 System.Environment.FailFast (.NET Framework 2.0 功能)来终止进程,而不是引发异常。

❌ 如果可能,请勿对正常控制流使用异常。

除了系统故障和具有潜在争用条件的操作之外,框架设计者应设计 API,使用户可以撰写不会引发异常的代码。 例如,可以在调用成员之前提供检查前置条件的方法,以便用户可以编写不引发异常的代码。

用于检查另一个成员的前置条件的成员通常称为测试人员,实际执行工作的成员称为执行者。

在某些情况下,Tester-Doer 模式可能会产生不可接受的性能开销。 在这种情况下,应考虑所谓的 Try-Parse 模式(有关详细信息,请参阅 异常和性能 )。

✔️ 请考虑引发异常对性能的影响。 每秒抛出速率超过 100 次可能会显著影响大多数应用程序的性能。

✔️ 请务必记录所有由可公开调用的成员因违反成员协定(而不是系统故障)而引发的异常,并将它们视为你协定的一部分。

作为协定一部分的异常不应从一个版本更改为下一个版本(即,异常类型不应更改,不应添加新异常)。

❌ 请勿包含可基于某些选项引发或不引发的公共成员。

❌ 请勿让公共成员将异常作为返回值或out参数。

从公共 API 返回异常,而不是引发异常,这会使基于异常的错误报告的许多好处无法实现。

✔️ 请考虑使用异常生成器方法。

从不同的位置引发相同的异常是很常见的情况。 为了避免代码膨胀,请使用创建异常并初始化其属性的帮助程序方法。

此外,引发异常的成员不会被内联。 将 throw 语句移动到生成器中可能会允许该成员内联。

❌ 请勿从异常筛选器块中引发异常。

当异常筛选器引发异常时,CLR 会捕获该异常,并且筛选器返回 false。 此行为与筛选器显式执行并返回 false 是无法区分的,因此很难进行调试。

❌ 请避免从 finally 块显式引发异常。 由于调用引发的方法而隐式引发的异常是可以接受的。

部分内容 © 2005, 2009 Microsoft 公司。 保留所有权利。

获得皮尔逊教育公司许可后重印自 框架设计准则:可重用 .NET 库的约定、习惯和模式 ,由 Krzysztof Cwalina 和 Brad Abrams 编写,并作为微软 Windows 开发系列中的出版物之一,于 2008 年 10 月 22 日由 Addison-Wesley Professional 出版。

另请参阅