代码改变世界

异常设计总结

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 包含无效值。