ASP.NET程序设计教程(第2版)
上QQ阅读APP看书,第一时间看更新

3.9 异常处理

异常是指程序在运行时产生的错误,借助C#的异常处理系统,能够以结构化的、可控制的方式来处理运行时错误。

异常处理的主要优点是,它可以自动加载许多错误处理代码,而在以前,开发人员必须手动把它们输入到任何大型程序中。

3.9.1 SystemException类

在C#中,使用类表示异常。

所有的异常类都由内置的异常类Exception派生而来,该类是System名称空间的一部分。

所有的异常类都是Exception类的子类。

SystemException类是Exception类的一个重要子类。CLR产生的所有异常都来自于该异常类。

System中的常用标准异常如下。

1)ArrayTypeMismatchException:所有存储的值类型与数组类型不兼容。

2)DivideByZeroException:被零除。

3)IndexOutOfRangeException:数组索引超出边界。

4)InvalidCastException:运行时强制转换无效。

5)OutOfMemoryException:没有足够的空闲内存支持程序继续执行。

6)OverflowException:运算溢出。

7)NullReferenceException:试图对空引用进行操作。

3.9.2 使用try和catch关键字

使用try和catch关键字配合来组织易错程序代码,是C#中典型的异常处理方式。以下是try-catch代码组织方式的结构。

查看下列代码。

上述代码运行之后,因为循环体中i的大小会超过数组元素的上界,会引发“数组索引超出边界”的异常,则代码会马上跳转到catch后的代码段,运行其中的代码。

3.9.3 使用异常处理的优点

异常处理的最大优点之一是,它允许程序对错误做出响应并继续执行。编写下列代码并运行。

成功运行上述代码之后,读者会发现,程序在运行到i等于1和i等于4时都会抛出“DivideByZeroException”即“被零除”的错误。在显示“不能被零除!”的错误信息之后,程序会继续运行。

3.9.4 使用多条catch子句

也可以使用多条catch子句接收异常,在发生不同异常的时候,由不同catch子句接收相应的异常。观察下列代码。

运行上述代码,会发现运行结果中出现两次“不能被零除!”的提示,最后出现“超出数组范围了!”的提示,即为使用多条catch子句接收异常的运行效果。

3.9.5 捕获所有异常

如果无法确定会出现哪种异常,仍然想使用异常处理的try-catch子句。则可以在catch后面不列出异常名称,而直接给出响应代码。观察下列程序。

注意:大多数情况下,不应该使用“捕获所有异常”的处理程序作为异常处理的方式。通常最好是分别处理代码产生的每个异常。不适当地使用“捕获所有异常”的处理程序会导致掩盖原本在测试期间可以捕获的错误。

3.9.6 手动抛出异常(throw)

在某些情况下,需要程序“制造”异常,即在上述异常都没有发生的情况下,手动抛出异常。这就需要使用“throw”关键字。抛出的异常必须使用new关键字,后跟一个具体的异常名称。如throw new DivideByZeroException()。观察下列代码。

3.9.7 finally语句

有时必须为程序离开try/catch块执行的操作编写一段代码。可以添加在try/catch结构后面的finally块中。

注意:无论try/catch块在什么时候因为什么条件结束,finally块只要存在都将必然执行。也就是说,不论try块是正常结束还是异常结束,最终都会执行finally块中的代码。即使try块中的代码或catch语句中的代码使得该方法返回,finally块也将执行。