<展现C#> 第七章 异常处理(rainbow 翻译)
。这是真的——在finally中的代码总 是会被执行的,不管是否具有异常条件。为了举例说明如何在两种情况下提供一些有意义的信息给用户, 我引进了新变量 bAllFine。bAllFine告诉finally 语段,它是否是因为一个异常或者仅是因为计算的顺利完成而被调用。 作为一个习惯了SEH程序员,你可能会想,是否有一个与__leave 语句等价的语句,该语句在C++中很管用。如果你还 不了解,在C++中的__leave 语句是用来提前终止 try 语段中的执行代码,并立即跳转到finally 语段 。 坏消息, C# 中没有__leave 语句。但是,在清单 7.5 中的代码演示了一个你可以实现的方案。 清单 7.5 从 try语句 跳转到finally 语句 1: using System; 2: 3: class JumpTest 4: { 5: public static void Main() 6: { 7: try 8: { 9: Console.WriteLine("try"); 10: goto __leave; 11: } 12: finally 13: { 14: Console.WriteLine("finally"); 15: } 16: 17: __leave: 18: Console.WriteLine("__leave"); 19: } 20: } 当这个应用程序运行时,输出结果为 try finally __leave 一个 goto 语句不能退出 一个finally 语段。甚至把 goto 语句放在 try 语句 段中,还是会立即返回控制到 finally 语段。因此,goto 只是离开了 try 语段并跳转到finally 语段。直到 finally 中的代码完成运行后,才能到达 __leave 标签。按这种方式,你可以模仿在SEH中使用的的__leave 语句。 顺便地,你可能怀疑goto 语句被忽略了,因为它是try 语句中的最后一条语句,并且控制自动地转移到了 finally 。为了证明不是这样,试把goto 语句放到Console.WriteLine 方法调用之前。尽管由于不可到达代码你得到了编 译器的警告,但是你将看到goto语句实际上被执行了,且没有为 try 字符串产生的输出。 7.2.3 使用try-catch-finally处理所有异常 应用程序最有可能的途径是合并前面两种错误处理技术——捕获错误、清除并继续执行应用程序。所有你要做的是在 出错处理代码中使用 try 、catch 和 finally语句。清单 7.6 显示了处理零除错误的途径。 清单 7.6 实现多个catch 语句 1: using System; 2: 3: class CatchIT 4: { 5: public static void Main() 6: { 7: try 8: { 9: int nTheZero = 0; 10: int nResult = 10 / nTheZero; 11: } 12: catch(DivideByZeroException divEx) 13: { 14: Console.WriteLine("divide by zero occurred!"); 15: } 16: catch(Exception Ex) 17: { 18: Console.WriteLine("some other exception"); 19: } 20: finally 21: { 22: } 23: } 24: } 这个例子的技巧为,它包含了多个catch 语句。第一个捕获了更可能出现的DivideByZeroException异常,而第二个 catch语句通过捕获普通异常处理了所有剩下来的异常。 你肯定总是首先捕获特定的异常,接着是普通的异常。如果你不按这个顺序捕获异常,会发生什么事呢?清单7.7中的 代码有说明。 清单7.7 顺序不适当的 catch 语句 1: try 2: { 3: int nTheZero = 0; 4: int nResult = 10 / nTheZero; 5: } 6: catch(Exception Ex) 7: { 8: Console.WriteLine("exception " + Ex.ToString()); 9: } 10: catch(DivideByZeroException divEx) 11: { 12: Console.WriteLine("never going to see that"); 13: } 编译器将捕获到一个小错误,并类似这样报告该错误: wrongcatch.cs(10,9): error CS0160: A previous |
查看所有评论
