C# 2010 从入门到精通 学习笔记5 第6章 管理错误和异常
本章内容
1. 使用 try,catch 和 finally 语句处理异常2. 使用 checked 和 unchecked 关键字控制整数溢出
3. 使用 throw 关键字从自己写的方法中抛出异常
4. 使用一个 finally 块,确保即使在发生异常之后,代码也总是在运行
6.1 处理错误
为了写一个可靠的 C#应用程序,你必须多多了解异常(exception)。
6.2 尝试代码和捕捉异常
代码要放到一个 try 块中(try 是 C#关键字)。
在 try 块后面紧接着写一个或多个 catch 处理程序(catch 也是 C#关键字),用它们处理任何发生的错误。每个catch 处理程序都负责捕捉并处理一种特定类型的异常。
6.2.1 处理异常
catch 处理程序采用与方法参数相似的语法来指定要捕捉的异常。
6.2.2 未处理的异常
如果 try 块是某个方法的一部分,那个方法将立即退出,并返回它的调用方法。如果它的调用方法使用了一个 try 块,运行时(runtime)会尝试定位 try 块之后的一个相匹配的 catch 处理程序,并执行它。如果调用方法没有使用 try 块,或者没有找到匹配的 catch处理程序,那个调用方法也将退出,并返回它的更上一级的调用方法……以此类推。如果最
终找到一个匹配的 catch 处理程序,就会运行它,然后从捕捉(到异常的)方法的 catch 处理程序之后的第一个语句继续执行。
终找到一个匹配的 catch 处理程序,就会运行它,然后从捕捉(到异常的)方法的 catch 处理程序之后的第一个语句继续执行。
重要提示:
捕捉了一个异常之后,将从“捕捉方法”中的 catch 处理程序之后的第一个语句继续,这个 catch 处理程序是实际捕捉到异常的 catch 块。程序控制不会返回当初造成异常的方法。
由内向外遍历了所有调用方法之后,假如“运行时”(runtime)找不到一个相匹配的 catch处理程序,整个程序就会终止,并报告一个未处理的异常。
6.2.3 使用多个 catch 处理程序
我们知道不同的错误可能抛出不同类型的异常。为了解决这个问题,可以提供多个 catch 处理程序。所有 catch 处理程序应依次列出。
6.2.4 捕捉多个异常
异常采用继承层次结构(inheritance hierarchy)进行组织。FormatException 和 OverflowException 异常都从属于一个名为SystemException(系统异常)的家族。这个家族还包含其他许多异常。SystemException本身又是一个名为 Exception 的家族的成员,捕捉Exception 相当于捕捉可能发生的一切异常。
注意:
Exception 包含众多的异常,其中许多异常是专门供.NET Framework 的各种组件使用的。虽然一些异常较难理解,但你至少应该知道如何捕捉它们。
提示:
如果你真的决定捕捉 Exception,可以从 catch 处理程序中省略它的名称,因为默认捕捉的就是 Exception。但是,并非总是推荐你这样做。在传入 catch 处理程序的异常对象中,可能包含与异常有关的一些有用的信息。使用这个版本的 catch 结构来访问,就无法利用这些信息。
在一个 try 块之后,应该将较具体的 catch处理程序放在泛化的 catch 处理程序之前。如果没有一个较具体的 catch 处理程序能够与异常匹配,就执行较泛化的 catch 处理程序。第一个catch处理程序捕捉到异常后,后面的catch处理程序都不会执行。
6.3 使用 checked 和 unchecked 整数运算
一个 C# 的 int 固定为 32 位。由于 int的大小是固定的,所以能轻松推算出它支持的值的范围:–2 147 483 648 到 2 147 483 647。
提示:
要在代码中引用 int 的最小或最大值,请分别使用 int.MinValue 和 int.MaxValue属性。
在 Visual Studio 2008 中,为了启用或禁用溢出检查,可以设置项目属性。在“项目”菜单中,请选择“YourProject 属性”选项(其中,YourProject 是当前项目的名称)。在项目属性对话框中,单击“生成”标签。单击选项卡右下角的“高级”按钮。在随后出现的“高级生成设置”对话框中,勾选或撤选“检查运算上溢/下溢”选项即可。
6.3.1 编写 checked 语句
重要提示:
只有直接放在 checked 块中的整数运算才会得到检查。例如,假如块中出现一个方法调用,就不会对调用的方法中的整数运算进行检查。
还可以使用 unchecked 关键字来创建一个强制不检查溢出的语句块。一个 unchecked 块中的所有整数运算都不会检查,永远不会抛出 OverflowException 异常。
6.3.2 编写 checked 表达式
使用 checked 和 unchecked 关键字,还可以控制对单独的整数表达式的溢出检查。只需使用圆括号将表达式封闭起来,并在之前附加 checked 或 unchecked 关键字。
重要提示:
不能使用 checked 和 unchecked 关键字来控制浮点(非整数)运算。checked和 unchecked 关键字只能适用于对 int 和 long 等数据类型执行的整数运算。浮点运算永远不会抛出 OverflowException——即使你让一个浮点数除以 0.0(.NET Framework 有专门表示无穷大的机制)。
6.4 抛出异常
throw 语句要抛出一个异常对象。
提示:
具体是否需要在一个方法内部显式地捕捉所有未处理的异常,取决于所设计的应用程序的本质。某些时候,有必要在尽量靠近异常抛出点的地方捕捉它。但在另一些时候,更好的做法是让异常顺着方法调用堆栈传回,由外层的方法来处理异常。
6.5 使用 finally 块
为了确保一个语句总是运行(不管是否抛出一个异常),需要将该语句放到一个 finally块中。