首页 > 代码库 > [C#] 学会处理异常

[C#] 学会处理异常

学会处理异常

  C# 程序员可使用 try 块对可能受异常影响的代码进行分区。 关联的 catch 块用于处理任何结果异常。 一个包含代码的 finally 块,无论 try 块中是否引发异常(例如,释放在 try 块中分配的资源),这些代码都会运行。 一个 try 块需要一个或多个关联的 catch 块或一个 finally 块,或两者。

  这里分别给出了一个 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             }

  【备注】不带有 catch 或 finally 块的 try 块将导致编译器错误。

 

捕获异常的 Catch 块

  catch 块可以指定要捕捉的异常的该类型。 类型规范称为“异常筛选器”。 异常类型应从 Exception 派生出来。 一般而言,不会将 Exception 指定为异常筛选器,除非您了解如何处理 try 块中可能引发的所有异常,或者您在 catch 块中包括了 throw 语句。

  具有不同异常筛选器的多个 catch 块可以串联在一起。 多个 catch 数据块的计算顺序是在代码中从顶部到底部,但是,对于所引发的每个异常,都只执行一个 catch 数据块。 与指定的准确类型或其基类最为匹配的第一个 catch 块被执行。 如果 catch 块没有指定匹配异常筛选器,则 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 块用于在再次引发异常之前,添加错误日志,这是我们常用的做法。

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

 

释放资源的 Finally 块

  可以使用 finally 块清理在 try 块中执行的操作。 如果存在,finally 块将在最后执行,在 try 块和任何匹配 catch 的块之后执行。 不管是否引发异常或者是否找到与异常类型匹配的 catch 块,finally 始终运行。

  可以使用 finally 块释放资源(如文件流、数据库连接和图形句柄),而不用等待由运行时中的垃圾回收器来完成对象。 其实,我们更建议使用 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         }

 

 


 

【博主】反骨仔

【原文】http://www.cnblogs.com/liqingwen/p/6193999.html 

【参考】微软官方文档

[C#] 学会处理异常