异常类
在C#里,异常处理就是C#为处理错误情况提供的一种机制.它为每种错误情况提供了定制的处理方式,并且把标志错误的代码预处理错误的代码分离开来.
对.net类来说,一般的异常类System.Exception派生于System.Object.还有许多定义好的异常类(例如:System.SystemExpection,SYstem.ApplicationException等),他们又派生于System.Exception类.其中System.ApplicationException类是第三方定义的异常类,如果我们要自定义异常类,那么就应派生于它.
在代码中对异常进行处理,一般要使用三个代码块:
第一个代码块:Try块的代码是程序中可能出现错误的操作部分.
第二个代码块是:Catch块的代码块用来处理各种错误的部分(可以有多个).必须正确排列捕获异常的catch子句,范围小的Exception放在前面的catch.即如果Exception之间存在继承关系,就应把子类的Exception放在前面的catch子句中
第三个代码块:finally快的代码用来倾力资源或执行要在try块末尾执行的其他操作(可以省略).且无论是否产生异常,Finally块都会执行.
异常处理
不管程序写的多好,异常都有可能发生,而程序也必须能够处理异常.所以我们要站在异常一定可能会发生的角度来编写异常处理程序,应对程序有可能发生的错误建立一个良好的异常处理策略.
异常产生的时候,我们想知道是什么情况导致了错误或异常.我们可以根据实际情况抛出具体类型的异常,方便捕捉到异常时做出具体的处理.在编写代码的过程中,可以使用系统已经定义好的相关异常类以及自定义的异常类,=来实例化并抛出我们需要的异常.如一个不可能实现的接口,我们可以抛出”System.NotSupportedException”的异常来告诉接口的调用者.
在处理异常的时候,我们应该将可处理的具体异常分别在catch块中做出相应处理,否则程序将终止运行.针对每一个异常,以不同的方式处理,避免对所有异常做出一样的处理.就像医生不能给孕妇和感冒开一样的药.我们在开开药的时候,是不是会被告诉一次吃多少,忌冷啥的注意事项,相同的道理,在异常产生的时候,需要给用户一个有好的提示(普通用户对异常的具体内容是不明白,这就需要我们给出相关的简要信息和解决方案,或告之联系方式,例如,我们怀孕了,怀孕的原理是啥?是什么导致怀孕?怀孕产生的效果是啥?咱们一般人可能不知道,我们只能收出现孕吐的情况了,咋办,找医生,咱们只是知道孕吐这是不正常的,这就出现了异常),并在可能的情况下给用户提供可能的选择(终止,重试,忽略),让用户来决定从程序的运行方法.同时,要将异常做日志记录(病例).但不是所有的异常都必须记录的,比如一些可预料并且能让程序解决的错误我们就不需要记录它.
记录异常我们可以采取以下方式:
1.在文件中记录异常,便于技术人员查看发生了什么情况,从而能改进程序.
2.在数据库中记录异常.数据库支持查询,这样在后期就能够对异常进行分类查询等操作,便于查看与管理
3.在Eventlog中记录:能够远程操作,方便系统管理员监控所有计算的异常.
除了具体的,可预料的异常外,(后面我要说啥?你猜?),还有未预料的错误,这类错误通常我们不愿意看到,但是肯定会发生,就像医生不愿意看到癌症的病例一样(因为代表着这个人不行了,应声通常希望大家都能好好的活着,别出现什么大病,我们还是要相信这个世界上还有好医生).但是这些不愿意看到的异常也只能暂时结束程序的运行,这里如果做好了日志就能为我们解决和调试问题带来了方便.还有,要避免使用try-catch但没有处理异常的情况,否则就相当于给异常放行(你有病,医生告诉你改则治,你不治.这就不行了,那你还去看医生干啥,,耽误医生救死扶伤).
处理完异常后,我们还要注意在finally块中释放资源,还原相关设置信息等收尾工作,也就是你的病好了以后,需要办理出院手续,和护士姐姐告个别.
在做异常处理的时候,最好能在应用程序所有的入口处(事件处理函数,主函数,线程入口)使用try-catch.但是不要在程序构造函数入口处添加try-catch,因为此处产生异常,他自己并没有能力处理,因为他还没有构造完毕,只能再想外层抛出异常.
在一般的情况下使用异常处理机制来处理错误,能是整个程序的结构清晰,代码简单(标志错误的代码预处理错误代码分离),但我们也不能盲目使用异常.而且使用异常,可能会在一定程度上影响程序的性能(C#中使用异常一般不会影响性能).对于一些简单的,能够提前避免的错误,我们还是应该在try块外面及早做出处理.
了解了基础的东西,再来看一下C#异常类相关总结
需要知道的是C#中所有的异常类,不管使自定义的,还是系统定义的,他们的基类都是Exception
另外说一下C#常见的异常类(没必要记住):知道有这么回事,你可以不看,不记,但是我不能不写.
异常类名 |
说明 |
SystemException |
该类是System命名空间中所有其他异常类的基类。(建议:公共语言运行时引发的异常通常用此类) |
ApplicationException |
该类表示应用程序发生非致命错误时所引发的异常(建议:应用程序自身引发的异常通常用此类) |
与参数相关的异常类 |
ArgumentException |
该类用于处理参数无效的异常,除了继承来的属性名,此类还提供了string类型的属性ParamName表示引发异常的参数名称。 |
FormatException |
该类用于处理参数格式错误的异常 |
与成员访问有关的异常 |
MemberAccessException |
该类用于处理访问类的成员失败时所引发的异常。失败的原因可能的原因是没有足够的访问权限,也可能是要访问的成员根本不存在(类与类之间调用时常用) |
MemberAccessException |
见下备注 |
与数组相关的异常类 |
IndexOutOfException |
该类用于处理下标超出了数组长度所引发的异常 |
ArrayTypeMismatchException |
该类用于处理在数组中存储数据类型不正确的元素所引发的异常 |
RankException |
该类用于处理维数错误所引发的异常 |
与IO有关的异常类 |
IOException |
该类用于处理进行文件输入输出操作时所引发的异常。详细见下备注 |
与算数相关的异常类 |
ArithmeticException |
该类用于处理与算术有关的异常,详细见下备注 |
备注:
MemberAccessException类的直接派生类:
i、FileAccessException类:该类用于处理访问字段成员失败所引发的异常
ii、MethodAccessException类:该类用于处理访问方法成员失败所引发的异常
iii、MissingMemberException类:该类用于处理成员不存在时所引发的异常
IOException类的5个直接派生类:
i、DirectionNotFoundException类:该类用于处理没有找到指定的目录而引发的异常。
ii、FileNotFoundException类:该类用于处理没有找到文件而引发的异常。
iii、EndOfStreamException类:该类用于处理已经到达流的末尾而还要继续读数据而引发的异常。
iv、FileLoadException类:该类用于处理无法加载文件而引发的异常。
v、PathTooLongException类:该类用于处理由于文件名太长而引发的异常。
ArithmeticException类的派生类:
i、DivideByZeroException类:表示整数货十进制运算中试图除以零而引发的异常。
ii、NotFiniteNumberException类:表示浮点数运算中出现无穷打或者非负值时所引发的异常。
|