C#的异常处理机制(try...catch...finally)
what?
在 C# 语言中异常与异常处理语句包括三种形式,即 try catch、try finally、try catch finally。
在上述三种异常处理的形式中所用到关键字其含义如下:
-
try:一个 try 块标识了一个将被激活的特定的异常的代码块。后跟一个或多个 catch 块。
-
catch:程序通过异常处理程序捕获异常。catch 关键字表示异常的捕获。
-
finally:finally 块用于执行给定的语句,不管异常是否被抛出都会执行。例如,如果您打开一个文件,不管是否出现异常文件都要被关闭。
-
throw:当问题出现时,程序抛出一个异常。使用 throw 关键字来完成。
why?
1.程序要健壮,必须要设计报错机制。
2.改进:一个函数或过程,会因为不同的原因产生错误,报错机制必须要把这些错误原因进行区分后,再汇报。
3.很多情况下,函数需要把详细的原因,用字符串的方式返回。try-catch方式相比于返回值,更强制性要求调用者处理“出错”的情况。
如何正确的使用?
-
只针对不正常的情况才使用异常
try { int i = 0; int[] arr = new int[5]; while (true) { arr[i] = 0; i++; } } catch (IndexOutOfRangeException e) { throw e; }
这是一个非常明显的错误,希望通过异常来中断循环而达到某种优化.其实不然.
-
CLR(Java JVM)对异常的块中的代码几乎不做优化.
-
而且创建、抛出、捕获异常都是十分昂贵的
-
正常的遍历数组并不会造成冗余的边界检查,现代的CLR(Java JVM)会做出优化
-
避免不必要的使用被检查的异常
“被检查的异常”是Java语言的一个很好的特性。与返回代码不同,"被检查的异常"会强迫程序员处理例外的条件,大大提高了程序的可靠性。
但是,过分使用被检查异常会使API用起来非常不方便。如果一个方法抛出一个或多个被检查的异常,那么调用该方法的代码则必须在一个或多个catch语句块中处理这些异常,或者必须通过throws声明抛出这些异常。无论是通过catch处理,还是通过throws声明抛出,都给程序员添加了不可忽略的负担。
适用于"被检查的异常"必须同时满足两个条件:第一,即使正确使用API并不能阻止异常条件的发生。第二,一旦产生了异常,使用API的程序员可以采取有用的动作对程序进行处理。
-
不要忽略异常
有些程序员会写出下面的代码
try {...} catch (Exception e) {}
或者
try {...} catch () {}
空的catch块会使异常达不到应有的目的,异常的目的是强迫你处理不正常的条件。忽略一个异常,就如同忽略一个火警信号一样 -- 若把火警信号器关闭了,那么当真正的火灾发生时,就没有人看到火警信号了。所以,至少catch块应该包含一条说明,用来解释为什么忽略这个异常是合适的。
以下程序会输出什么
static void Main(string[] args){ try { Console.WriteLine("Hello"); throw new ArgumentNullException(); } catch (ArgumentNullException) { Console.WriteLine("A"); } catch (Exception) { Console.WriteLine("B"); } finally { Console.WriteLine("C"); } Console.ReadKey(); }
参考答案