来自微软关于异常处理的17条军规
1. 不要返回错误代码。异常是报告框架中的错误的主要手段。
这个就不讨论了,异常包含的信息量远不是几个错误代码可以替代的.
2. 通过引发异常来报告执行故障。如果某一成员无法按预期方式成功执行,则应将这种情况视为一个执行故障并引发一个异常。
例如函数的参数检测,参数不符合输入要求,就应该引发一个异常.另外还有很多情况,只要程序无法按照预定的逻辑执行下去,就应该引发一个异常.
3.如果代码遇到继续执行则不安全的情况,应考虑通过调用 System.Environment.FailFast(System.String)(.NET Framework 2.0 中的一种功能)来终止进程,而不是引发异常。
代码遇到异常,如果异常不是可以接受的.那么就应该立即终止.避免更严重的后果.“FailFast 方法使用 message 参数向 Windows Application 事件日志写入日志项,创建应用程序的转储,然后终止当前进程。 如果应用程序状态为损坏且无法修复,并且执行应用程序的 try-finally 块和终结器将损坏程序资源,请使用 FailFast 方法而不是 Exit 方法终止应用程序。FailFast 方法终止当前进程并执行任何 CriticalFinalizerObject 对象,但不执行任何活动 try-finally 块或终结器。 ”
4. 尽可能不对正常控制流使用异常。
就是不能用异常来控制业务逻辑.异常是不应该属于正常运作范围.你的程序Catch部分除了写日志,释放资源(更多时候应该放到finally块)和抛出异常外,不应该有任何业务逻辑.
5. 考虑引发异常的性能影响.
异常是极其消耗资源的,当大量引发异常的时候会导致性能问题.所以,结合上一条,不要用异常控制流程.就是你的代码正常使用下,是不需要触发异常的.
6. 不要包含可以根据某一选项引发或不引发异常的公共成员。
就是不要创建类似function(bool isThrowException)这样的函数或方法,结合第3条理解,这样的方法已经触犯了用异常控制流程的禁忌.触发异常必须抛出,一直抛到你处理异常的地方.
7. 不要包含将异常作为返回值或输出参数返回的公共成员。
同理,触犯第3条军规.
8. 考虑使用异常生成器方法。从不同的位置引发同一异常会经常发生。为了避免代码膨胀,请使用帮助器方法创建异常并初始化其属性。
使用异常帮助类. 或者这里是说自定义异常?经常发生的自定义异常可以用生成器的方法生成?或者封装异常生成类。减少资源调用。
9. 避免从 finally 块中显式引发异常。可以接受因调用引发异常的方法而隐式引发的异常。
Finally模块是处理异常的地方,不应该在这个地方引发异常.但是如果要调用引发异常的方法做处理而引发的异常则可以接受。
10. 考虑引发 System 命名空间中的现有异常,而不是创建自定义异常类型。如果错误状态可以通过不同于现有任何其他异常的方法以编程方式进行处理,则要创建并引发自定义异常。否则,引发一个现有异常。
尽量引发系统异常,除非必要不必创建自定义异常类。只要日志写得好,处理异常会很方便。
11. 引发适当的最具体(派生程度最大)的异常。
就是尽量让异常靠近实际错误情况。而不是一律抛出SystemException了事。
12.不要引发 System.Exception 或 System.SystemException。
因为引发最普遍的异常并不能更有效的帮助人们认清楚错误和及时进行错误处理。Exception越具体,帮助越大。
13. 避免捕捉 System.Exception 或 System.SystemException,在顶级异常处理程序中除外。
除非在顶级最终写Log的时候,否则不应该捕捉最普遍的异常。个人因为只应该在顶级处理捕捉异常。底层异常一律往上抛即可。
14. 对于可能在常见方案中引发异常的成员,可以考虑使用 Tester-Doer 模式来避免与异常相关的性能问题。
例如,对于函数的参数问题,就必须创建检测类检测输入是否正确.
对于可能在常见方案中引发异常的成员,可以考虑使用 TryParse 模式来避免与异常相关的性能问题。
TryParse模式参考int.TryParse等.就是创建正常运行的条件避免抛出异常.
15. 一般不要隐藏异常转而抛出其他异常。
不要将抛出的异常拦截转而抛出自定义的异常。除非抛出的异常而包含该原始异常,否则对异常了解非常不利。
16. 定要在所有异常上都提供(至少是这样)下列常见构造函数。确保参数的名称和类型与在下面的代码示例中使用的那些相同。
自定义异常MS推荐重载:
public class NewException : BaseException, ISerializable
{
public NewException()
{
// Add implementation.
}
public NewException(string message)
{
// Add implementation.
}
public NewException(string message, Exception inner)
{
// Add implementation.
}
// This constructor is needed for serialization.
protected NewException(SerializationInfo info, StreamingContext context)
{
// Add implementation.
}
}
17.在引发异常时为开发人员提供丰富且有意义的消息文本。
"消息应说明导致异常的原因并清楚描述避免该异常需采取的操作。消息应针对开发人员设计。确保异常消息的语法正确。顶级异常处理程序可以向应用程序终端用户显示异常消息。确保消息文本的每个句子都是以句号(“。”)结尾。这样,向用户显示异常消息的代码不必处理开发人员忘记最后面的句号的情况,这种处理相当麻烦而且代价很大。避免在异常消息中使用问号(“?”)和感叹号(“!”)。不要在不要求相应权限的异常消息中透露安全敏感信息。"