异常设计总结
2017-06-04 17:03 Dirichlet 阅读(313) 评论(0) 编辑 收藏 举报0. 异常的优点
a. 有堆栈信息,利于定位程序故障。
b. 程序显得整洁,是的正常的业务逻辑和异常处理分开。返回值形式会容易出现层层迭代,返回值检查和正常逻辑混在一起。
c. 异常处理部分可以用于确保资源的释放。Finally, Close
1. 抛出异常
设计一个对外的接口,怎么抛出以及什么时候抛出异常?
a. 传入参数不属于函数执行时的正常范围。
b. 执行过程中遇到非正常情况可以抛出异常,无法正常操作时可抛出异常,比如网络/数据库连接中断,文件读取越界。
c. 捕捉了底层的异常,可以考虑包装原始异常,继续往上抛或直接处理,记log。
d. 有些函数是否应该抛出异常。Equals, int.Parse,
2. 如何处理异常
-a:不要捕捉System.Exception,也就是不要捕捉所有异常。直捕捉预料之内的异常。
比如任何函数都有可能抛出OutOfMemoryException, StackOverFlowException异常,如果捕捉System.Exception,然后吃掉,程序的运行不可预期,不如直接退出。
a. 捕捉的异常可能是预期内的,可以正常处理。
b. 可以正常处理的异常,捕捉并处理它,也就是了解异常产生的条件,比如FileNotFoundException。
只捕捉能正确处理的异常,不能处理允许在调用堆栈中往上抛。
c. 捕捉了底层的异常,可以考虑包装原始异常成为具体的,对上层调用有意义的异常,然后抛出或者记log。
捕捉并引发异常时,首选空引发,因为这样可以保持异常调用堆栈信息。
public void MethodWithBadCatch(Object anObject) { try { DoWork(anObject); } catch (ArgumentNullException e) { System.Diagnostics.Debug.Write(e.Message); // This is wrong. throw e; // Should be this: // throw; } }
3.
-a. 有些函数是否应该抛出异常。Equals, int.Parse?
a. 减少异常引发的可能性,利用Tester-Doer, TryParse模式。
编写不引发异常的API。int.TryParse // 模式
用户调用之前检查参数,可以编写不引发异常的代码。// Tester-Doer模式
// Method that can potential throw exceptions often. public static void ProcessMessage(string message) { if(message == null) { throw new ArgumentNullException("message"); } }
if (message != null) { Doer.ProcessMessage(message); }
// Samples
FileStream.Read方法引发的异常
异常 | 条件 |
---|---|
ArgumentNullException |
array 为 null。 |
ArgumentOutOfRangeException |
offset 或 count 为负。 |
NotSupportedException |
流不支持读取。 |
IOException |
发生了 I/O 错误。 |
ArgumentException |
offset 和 count 描述 array 中的无效范围。 |
ObjectDisposedException |
在流关闭后调用方法。 |
FileStream 构造函数 (String, FileMode) 引发的异常
异常 | 条件 |
---|---|
ArgumentException |
path 为空字符串 (""),只包含空格,或者包含一个或多个无效字符。 - 或 - path 引用非文件设备,如“contact:”,“com1:”,“lpt1:”等. 在 NTFS 环境中。 |
NotSupportedException |
path 引用非文件设备,如“contact:”,“com1:”,“lpt1:”等. 在非 NTFS 环境中。 |
ArgumentNullException |
path 为 null。 |
SecurityException |
调用方没有所要求的权限。 |
FileNotFoundException |
找不到文件,比如当 mode 是 FileMode.Truncate 或 FileMode.Open 而 path 指定的文件不存在时。 文件必须已经以这些模式存在。 |
IOException |
发生 I/O 错误,比如指定 FileMode.CreateNew 而 path 指定的文件已存在。 - 或 - 流已关闭。 |
DirectoryNotFoundException |
指定的路径无效,比如在未映射的驱动器上。 |
PathTooLongException |
指定的路径、文件名或者两者都超出了系统定义的最大长度。 例如,在基于 Windows 的平台上,路径必须小于 248 个字符,文件名必须小于 260 个字符。 |
ArgumentOutOfRangeException |
mode 包含无效值。 |