CSharp(C#)语言_异常和异常处理

什么是异常

  异常是程序中的运行时错误,它违反了系统约束或应用程序约束,或出现了在正常操作时未预料的情形

try语句

try语句用来指明为避免出现异常而被保护的代码段,并在发生异常时提供代码处理异常

  • try语句由3个部分组成:
    • try块包含为避免出现异常而被保护的代码
    • catch子句部分含有一个或多个catch子句。这些是处理异常的代码段,它们也称为是异常处理程序
    • finally块含有在所有情况下都要被执行的代码,无论有没有异常发生

CSharp(C#)语言_异常和异常处理

异常类

  有许多不同类型的异常可以在程序中发生。BCL定义了许多类,每一个类代表一个指定的异常类型。当一个异常发生时,CLR:

  • 创建该类型的异常对象;
  • 寻找适当的catch子句以处理它。

所有异常类都从根本上派生自System.Exception类
CSharp(C#)语言_异常和异常处理

属 性 类 型 描 述
Message string 这个属性含有解释异常原因的消息
StackTrace string 这个属性含有描述异常发生在何处的信息
InnerException Exception 如果当前异常是由另一个异常引起的,这个属性包含前一个异常的引用
HelpLink string 这个属性可以被应用程序定义的异常设置,为异常原因信息提供URN或URL
Source string 如果没有被应用程序定义的异常设定,那么这个属性含有异常所在的程序集的名称

catch子句

catch子句处理异常。有3种形式,允许不同级别的处理

CSharp(C#)语言_异常和异常处理
  一般catch子句能接受任何异常,但不能确定引发异常的类型。这只允许对任何可能发生的异常的普通处理和清理
  特定catch子句形式把一个异常类的名称作为参数。它匹配该指定类或派生自它的异常类的异常
  带对象的特定catch子句提供关于异常的最多信息。它匹配该指定类的异常,或派生自它的异常类的异常。它还给出一个异常实例(称为异常变量),是一个对CLR创建的异常对象的引用。可以在catch子句块内部访问异常变量的属性,以获取关于引起的异常的详细信息

catch子句段

  catch子句的目的是允许你以一种优雅的方式处理异常。如果你的catch子句接受一个参数,那么系统会把这个异常变量设置为异常对象,这样你就可以检查并确定异常的原因。如果异常是前一个异常引起的,你可以通过异常变量的InnerException属性来获得对前一个异常对象的引用。
  catch子句段可以包含多个catch子句
当异常发生时,系统按顺序搜索catch子句的列表,第一个匹配该异常对象类型的catch子句被执行。因此,catch子句的排序有两个重要的规则。具体如下:

  • 特定catch子句必须以一种顺序排列,最明确的异常类型第一,直到最普通的类型
  • 如果有一个一般catch子句,它必须是最后一个,并且在所有特定catch子句之后。不鼓励使用一般catch子句,因为它允许程序继续执行隐藏错误,让程序处于一种未知的状态。应尽可能使用特定catch子句

CSharp(C#)语言_异常和异常处理

finally块

如果程序的控制流进入了一个带finally块的try语句,那么finally始终会被执行

  • 如果在try块内部没有异常发生,那么在try块的结尾,控制流跳过任何catch子句并到finally
  • 如果在try块内部发生了异常,那么在catch子句段中无论哪一个适当的catch子句被执行,接着就是finally块的执行

CSharp(C#)语言_异常和异常处理

为异常寻找处理程序

当程序产生一个异常时,系统查看该程序是否为它提供了一个处理代码

  • 如果在try块内发生了异常,系统会查看是否有任何一个catch子句能处理该异常
  • 如果找到了适当的catch子句,以下3项中的1项会发生
    • 该catch子句被执行
    • 如果有finally块,那么它被执行
    • 执行在try语句的尾部继续(也就是说,在finally块之后,或如果没有finally块,就在最后一个catch子句之后)

CSharp(C#)语言_异常和异常处理

更进一步搜索

 &wmsp;如果异常在一个没有被try语句保护的代码段中产生,或如果try语句没有匹配的异常处理程序,系统将不得不更进一步寻找匹配的处理代码。为此它会按顺序搜索调用栈,以看看是否存在带匹配的处理程序的封装try块
CSharp(C#)语言_异常和异常处理
处理异常的一般法则
CSharp(C#)语言_异常和异常处理

抛出异常

不细说。。。