一般而言,所谓“异常”是指:程序在运行时发生的不正常的错误情况。而当异常状况产生时,若能通过捕捉这些异常情况来加以处理,便能在程序执行时避免错误的产生,从而避免陷入无法顺利运行程序的窘境。
<一> Exception异常类
Exception类表示在应用程序执行期间发生的错误。System.Exception类是所有异常的基类型。此类具有一些所有异常共享的值得注意的属性:
属性 |
访问权限 |
类型 |
描述 |
HelpLink |
只读 |
String |
获取或设置指向此异常所关联帮助文件的链接 |
InnerException |
只读 |
Exception |
获取或导致当前异常的Exception实例 |
Message |
只读 |
String |
获取描述当前异常的消息 |
Source |
只读 |
String |
获取或设置导致错误的应用程序或对象的名称 |
StackTrace |
只读 |
String |
获取当前异常发生所经历的方法的名称和签名 |
TargetSite |
只读 |
MethodBase |
获取引入当前异常的方法 |
Exception类是所有异常的基类。当发生错误时,系统或当前正在执行的应用程序通过引发包含关于该错误的信息的异常来报告错误。异常发生后,将由该应用程序或缺少异常处理程序进行处理。
异常类型支持下面的功能:
◆ 描述错误的可读文本。当异常发生时,运行库产生文本消息,通知用户错误的改选并提供解决该问题的操作建议。此文本消息保存在异常对象的Message属性中,在创建异常对象过程中,可以将文本字符串传递给构造函数以描述该特定异常的详细信息。如果没有向构造函数提供错误信息参数,则将使用缺省错误信息。
◆ 发生异常时调用堆栈的状态。StackTrace属性包含可以用来确定代码中错误发生位置的堆栈跟踪。堆栈跟踪列出所有调用的方法和源文件中这些调用所在的行号。
基类Exception存在两类异常
◆ 从SystemException派生的预定义公共语言运行库异常类。
◆ 从ApplicationException派生的用户定义的应用程序异常类。
1、异常层次结构
有两种类型的异常:由执行程序生成的异常和由公共语言运行库生成的异常。另外,还有由应用程序或运行库引发的异常的层次结构。
Exception是异常的基类。若干异常类直接从Exception继承,其中包括ApplicationException和SystemException。这两个类构成几乎所有运行库异常的基础。错误发生时,运行库引发SystemException的适当派生类。这些错误是失败的运行库检查(如数组走出界限错误)导致的,它们可在任何方法的执行过程中发生。ApplicationException由用户程序引发,而不是由运行库引发。如果设计创建新异常的应用程序,应从ApplicationException类派生那些异常。不建议捕捉SystemException,在应用程序中引发SystemException也不是好的编程做法。
最严重的异常,即那些由运行库引发或在不可恢复的情况中引发的异常包括ExecutionEngineException、StackOverflowException和OutOfMemoryException。交互操作异常从SystemException派生并由ExternalException进一步扩展。例如,COMException是COM Interop操作过程中引发的异常,它从ExternalException派生。Win32Exception和SEHException也从ExternalException派生。
2、运行库异常层次结构
运行库有一组SystemException派生的基异常,它在执行各指令时引发这些异常。
下表是运行库提供的标准异常以及派生类的创建条件
异常类型 |
基类型 |
说明 |
示例 |
Exception |
Object |
所有异常的基类 |
无(使用此异常的派生类) |
SystemException |
Exception |
所有运行时生成的错误的基类 |
无(使用此异常的派生类) |
IndexOutOfRangeException |
SystemException |
仅当错误地对数据进行索引时,才由运行库引发 |
在数组的有效范围外对数组进行索引:arr[arr.length+1] |
NullReferenceException |
SystemException |
仅当引用空对象时,才由运行库引发 |
Object 0=null; o.ToString(); |
InvalidOperationException |
SystemException |
当处于无效状态时,由方法引发 |
从基础集合移除Item后调用Enumerator.GetNext() |
ArgumentException |
SystemException |
所有参数异常的基类 |
无(使用此异常的派生类) |
ArgumentNullException |
ArgumentException |
由不允许参数为空的方法引发 |
String s=null; “Calculate”.IndexOf(s); |
ArgumentOutOfRangeException |
ArgumentException |
由难参数是否位于给定范围内的方法引发 |
String s=”string”; s.Chars[9]; |
ExternalException |
SystemException |
在运行库的外部环境中发生或针对这类环境的异常的基类 |
无(使用此异常的派生类) |
COMException |
ExternalException |
封装COM HRESULT信息的异常 |
在COM Interop中使用 |
SEHException |
ExternalException |
封装Win32结构化异常处理信息的异常 |
在非托管代码interop中使用 |
3、常用异常类
下表是C#抛出的常用异常
异类类 |
描述 |
System.OutOfMemoryException |
当试图通过new来分配内存失败时抛出 |
System.StackOverflowException |
当执行栈太多未完成的方法调用耗尽时抛出;典型情况为浓度、庞大的递归 |
System.NullReferenceException |
当null引用在造成引用的对象被需要的情况下使用时抛出 |
System.TypeInitializationException |
当一个表态构造函数抛出一个异常,并且没有任何catch语句来俘获它的时候抛出 |
System.ArrayTypeMismatchException |
当因为存储元素的实例类型与数组的实际类型不匹配而造成一个数组存储失败时抛出 |
System.InvalidCastException |
当一个从基本类型或接口到一个派生类型的转换在支持时失败抛出 |
System.IndexOutOfRangeException |
当试图通过一个比零小或者超出数组边界的下标来索引一个数组时会引发此异常 |
System.MulticastNotSupportedException |
当试图合并两个非空代表失败时抛出;因数代表类型没有void返回类型 |
System.ArithmeticException |
一个异常的基类,在算术运算时发生,如DivideByZeroException和OverflowException |
System.DivideByZeroException |
当试图用整数类型数据除以零时抛出 |
System.OverflowException |
当checked中的一个算术运算溢出时抛出 |
System.ArithmerticException |
在算术运算期间发生的异常(如System.DivideByZeroException和System.OverflowException)的基类 |
System.AccessException |
访问一个类型成员(如一个方法或域)失败 |
System.ArgumentException |
方法参数非法 |
BadImageFormatException |
图像格式错误 |
System.CoreException |
被运行期异常抛出基类 |
FieldAccessException |
访问一个域出错 |
FormatException |
参数格式错误 |
MethodAccessException |
无效的方法调用 |