学会管理极度

捕获异常的 Catch 块

catch块可以指定要捕捉的异常类型,又可以称为“异常筛选器”。
异常类型都是从Exception派生出来。 一般来说,我们不会将所有异常的基类
System.Exception指定为要 catch
的“异常筛选器”,除非你非常了解如何处理由try块引发的所有异常,或者在catch块中包括了throw语句。

  多个catch块可以串联在一起(要求异常筛选器不同)。
多个catch块的执行顺序是:在代码中,从顶部到底部,但是,对于在运行时所引发的每一个异常,程序都只会执行一个catch数据块。
与指定的异常类型或它的基类相匹配的第一个catch块,才会被执行。通常,我们需要将最特殊(最具体或者说派生程度最最最高)的异常类,这段catch块放在所有
catch 块的最前面,而他们的基类 Excetion 的 catch 块就放在最后。

  在以下条件为真时,你应该选择 catch 异常:

  • 了解引发异常的原因,并可实现有选择性的恢复。例如,在捕获FileNotFoundException
    时你可以提示用户“文件找不到”和“请输入新的文件名”等。

  • 你也可以新建一个更具体或者说更具有代表性的异常,并选择引发该异常。

 1         double GetNum(double[] nums,int index) 2         { 3             try 4             { 5                 return nums[index]; 6             } 7             catch (IndexOutOfRangeException e) 8             { 9                 throw new ArgumentOutOfRangeException("Sorry, 你想要的索引已经超出界限!");10             }11         }

  

  希望在将异常抛出去时,我们通常会选择处理部分异常。
在下面这个示例中,catch块在再次 throw 异常之前,添加错误日志。

 1             try 2             { 3                 //尝试访问系统资源 4             } 5             catch (Exception e) 6             { 7                 //伪代码:记录错误日志 8                 log.Error; 9 10                 //再重新抛出错误11                 throw;12             }

C# 基础回顾系列

  《C# 知识回顾 – 序列化》

  《C# 知识回顾 – 表达式树 Expression Trees》

  《C# 知识回顾 – 特性 Attribute》、《剖析 AssemblyInfo.cs –
了解常用的特性 Attribute》

  《C# 知识回顾 – 委托 delegate》、《C# 知识回顾 – 委托 delegate 》

  《C# 知识回顾 – 事件入门》、《C# 知识回顾 – Event 事件》

  《string 与 String,大 S 与小 S 之间没有什么不可言说的秘密》

  《C# 知识回顾 – 异常介绍》、《C# 知识回顾 – 学会使用异常》


反骨仔

微软官方文档

释放资源的 Finally 块

  可以使用finally块释放在try块中需要执行释放资源的操作。
如果存在finally块,它将在最后执行,也就是在try块和任何匹配catch块之后执行。
不管是否引发异常或者说是否找到与异常类型相匹配的catch块,finally块它始终都会运行。

  可以使用finally块释放资源(如 IO 流、DB
连接和图形句柄),而不要等待运行时中的垃圾回收器来完成对象资源的回收。
其实,我们更建议使用using 语句。

  在下面的示例中,我使用finally块关闭在try块中打开的文件。注意,在关闭文件之前你应该要检查该文件句柄的状态。
如果try块无法打开文件,则文件句柄的值依然为null,这时,finally块就不会尝试关闭它。
或者说,如果在try块中成功打开该文件,则finally块才会成功地关闭正在打开的文件。

 1         static void Main(string[] args) 2         { 3             FileStream fs = null; 4             FileInfo fi = new System.IO.FileInfo("C:\\小二和小三的故事.txt"); 5  6             try 7             { 8                 fs = fi.OpenWrite(); 9                 fs.WriteByte(0);10             }11             finally12             {13                 // 记得判断 null 哦,不然可能触发其它异常14                 if (fs != null)15                 {16                     fs.Close();17                 }18             }19 20         }

学会处理异常

  你可以使用try块来对你觉得可能会出现异常的代码进行分区。
其中,与之关联的catch块可用于处理任何异常情况。
一个包含代码的finally块,无论try块中是否在运行时引发异常(例如,释放在try块中分配的资源),这些
finally 块的代码都会运行。
这些“异常部分”:可以由一个try块、一个或多个关联的catch块、一个finally块分别组合。

  这里我列举了 3
种情况:一个try-catch语句,一个try-finally语句,和一个try-catch-finally语句。

  try-catch:

 1         static void Main(string[] args) 2         { 3             try 4             { 5                 //需要执行的代码 6             } 7             catch (Exception e) 8             { 9                 //这里可以获取到被捕获的异常10                 //你需要知道自己应该如何处理该异常11             }12         }

  

  try-finally:

1             try2             {3                 //需要执行的代码4             }5             finally6             {7                 //在 try 块后执行的代码8             }

  

  try-catch-finally:

 1             try 2             { 3                 //需要执行的代码 4             } 5             catch (Exception e) 6             { 7                 //这里处理异常 8             } 9             finally10             {11                 //在 try 块(也可能是 catch 块)后执行的代码12             }

  不带有catchfinally块的try块将导致编译器错误。

相关文章