C#异常处理

发布日期:2018-03-01    浏览次数:411

1C#中所有的异常类型都继承自System.Exception,也就是说,System.Exception是所有异常类的基类. 总起来说,其派生类分为两种:

1).SystemException类: 所有的CLR提供的异常类型都是由SystemException派生。
2). ApplicationException类: 由用户程序引发,用于派生自定义的异常类型,一般不直接进行实例化。

System.Exception 类

System.Exception 类是所有异常的基类型。此类具有一些所有异常共享的值得注意的属性:

1).Message 是 string 类型的一个只读属性,它包含关于所发生异常的原因的描述(易于人工阅读)

2).Source 导致异常的应用程序名或对象名

3).Data    这个属性可以给异常添加键/值语句,以提供关于异常的额外信息

4).StackTrace 栈上方法调用的详细信息,它有助于跟踪抛出异常的方法

5).InnerException 是 Exception 类型的一个只读属性。如果它的值不是 null,则它所引用的是导致了当前异常的那个异常,即表示当前异常是在处理那个 InnerException 的 catch 块中被引发的。否则,它的值为 null,则表示该异常不是由另一个异常引发的。

区别:

  1)ApplicationException 由用户程序抛出,也就是说要在代码中编写throw ApplicationException。
   这个类是为了区别CLR抛出的异常而设计的,所以根据这一原则,我们定义自己的异常类的时候要从ApplicationException继承。
 (2)SystemException 由CLR抛出,例如数组越界,类型转换错误等,都会被此异常捕捉,因为InvalidCastException、InvalidOperationException等异常都是继承于SystemException的。

2导致异常的原因(可以以两种不同的方式引发异常)

1).使用 throw主动抛出异常,用于立即无条件地引发异常。控制永远不会到达紧跟在 throw 后面的语句。

2).在执行 C# 语句和表达式的过程中,有时会出现一些例外情况,使某些操作无法正常完成,此时就会引发一个异常。例如,在整数除法运算中,如果分母为零,则会引发 System.DivideByZeroException。有关可能以此方式引发的各种异常的列表。

3、匹配

   一个try块必须有一个catch块或finally块与其对应,如下几种使用方式都是可以的:try…catch 、try…finally、try…catch.finally。一个try中可以有多个catch,但是只能有一个finally;try至少要有catch或者finally,不能单独try;try ,catch,finally中可以均嵌套try_catch_finally;

4、匹配顺序

   如果try块中无异常抛出,则CLR不会执行任何catch块。Catch关键字后的圆括号中的表达式称为捕捉类型,每个catch块只能指定一个捕捉类型,C#要求捕捉类型只能是 System.Ex ception类或其派生类。当try块出现了异常,CLR会以catch编码的顺序从上向查找与异常类型相匹配的catch 块,所以“窄”的异常类型应该放在最前面的catch 块中,最“宽”的异常类型应该放在最后面的catch块中。假如有如下继承关系的伪代码:

Class 类A:类B:类C:System.Exception

我信通常应该如下来放置catch筛选器类型:

try{//}

catch(A)

{}

catch(B)

{}

catch(C)

{}

finally

{}

5、异常的处理方式

1).程序在try块中发生异常或遇到一条throw语句,会立刻查找与这个try对应的catch块(根据该异常的运行时类型来确定),如果有多个与try对应的catch块,则会查找与catch块对应的异常类(注意,没有指定异常类的 catch 子句和catch(Exception)一样可以处理任何异常)。

2).程序在try块中发生异常或遇到一条throw语句,系统会立即退出栈上所有的方法调用,异常处后面的代码都不会执行,此时,中间方法调用中的所有局部变量都会超出作用域。

3).无论是否抛出异常,finally块都会执行,可以用于清理资源或执行通常要在try或catch块末尾执行的其他操作(如删除对象或关闭已打开的对象)。

4).try对应多个catch块时,程序只执行它在可用的catch块列表中第一个合适的catch块,所以,最先编写catch块用于处理非常特殊的错误,接着比较一般的块,顺序很重要。

5).嵌套try...catch,外层抛出的异常外层catch捕获处理,内层抛出的异常内层catch捕获处理,如果内层对应没有catch,则外层Catch处理,如外层也没Catch,则.NET运行库处理。

6).在Catch中抛出或发生异常,抛出或发生异常后面的代码不会运行,执行finally块中的代码后跳出当前等级的异常处理,由上层Catch捕获,如果没有,则由.NET运行库捕获。

7).有时抛出一个异常后,代码中没有catch块能够处理这类异常。实际上.NET运行库把整个程序放在另一个更大try块中,对每个.NET程序它都会这么做。它可以捕获任何类型的异常,程序流会退出程序,由.NET运行库中的catch块捕获它。

6、用户自定义异常

创建自定义异常类应严格遵循几个原则
1). 声明可序列化(用于进行系列化,当然如果你不需要序列化。那么可以不声明为可序列化的)
2). 添加一个默认的构造函数
3). 添加包含message的构造函数
4). 添加一个包含message,及内部异常类型参数的构造函数
5). 添加一个序列化信息相关参数的构造函数

7、异常捕获注意

避免在finally内撰写无效代码

避免嵌套异常

避免“吃掉”异常

为循环增加Tester-Doer模式而不是将try-catch置于循环内

参见:

http://www.cnblogs.com/DswCnblog/p/5340213.html

http://www.cnblogs.com/solan/archive/2012/08/09/CSharp10.html

http://www.cnblogs.com/aehyok/p/3761583.html


本文网址:https://www.wyxxw.cn/blog-detail-2-6-825.html

返回列表

非特殊说明,本文版权归原作者所有,转载请注明出处

提示:本站所有资源仅供学习与参考,请勿用于商业用途。图片来自互联网~如侵犯您的权益,请联系QQ:1067507709.

提示:转载请注明来自:http://blog.csdn.net/tangtiantian520/article/details/73548987 。 转载人:momo