第六章 管理错误和异常

1.多个catch

try
{
      ......
}
catch(FormatException f)
{
      ......
}
catch(OverflowException o)
{
      ......
      //这里抛出FormatException,该异常会传递给调用栈的上一级
}

2.捕捉多个异常
如何保证所有可能的异常都被捕捉并处理?
这个问题的关键在于各个异常之间的关系。异常用继承层次结构进行组织。
FormatException和OverflowException异常都属于SystemException家族。该家族还包含其它许多异常。
SystemException本身又是Exception家族的成员,而Exception是所有异常的"老祖宗"。
捕捉Exception相当于捕捉所有可能发生的异常。

try
{
      .....
      //这里抛出FormatException,最终运行哪一个?
      //异常发生后将运行由 “运行时” 发现的第一个匹配的异常处理程序,其它处理程序会被忽略。
}
catch(FormatException f)
{}
catch(Exception e)
{}

3.筛选异常
用when关键字加一个布尔表达式,可筛选与catch处理程序匹配的异常,确保异常处理程序仅在满足额外的条件时才促发。

bool isConnect = ...;
try
{
      ....
}
catch(Exception e) when (isConnect)
{
      //仅在isConnect为true时才处理异常
}

4.使用checked和unchecked整数运算
checked语句是以checked关键字开头的代码块。checked语句中的任何整数运算溢出都抛出OverflowException异常。

int number = int.MaxValue;
checked
{
      int number = 1;
      Calculate(1);//只有直接在checked块中的整数运算才会检查。对于块中的方法调用,不会检查所调用方法中的整数运算
}

int Calculate(int num)
{
      int willThrow;
      checked
      {
            willThrow = number + num;// checked关键字检查算数溢出。number++求值后已经溢出,所以会抛出OverflowException
            Console.WriteLine($"{number}"); // 永远都执行不到这里
      }
      return willThrow
}

unchecked则不检查算术溢出,不会抛出OverflowException。
也可以在项目属性来启用或禁用溢出检查。右击项目 -> (最底部) 属性 -> 生成 -> (最底部) 高级-> 检查算数溢出

5.使用finally
抛出异常会改变程序的执行流程。
当catch处理程序运行完毕,会从整个try/catch块之后的语句继续,而不是从抛出异常的语句之后继续。

int number = int.MaxValue;
try
{
    long storage;
    checked
    {
        storage = number++;//算术溢出,抛出OverflowException。
    }
      //下面的代码将不会被执行!
    Console.WriteLine("aaaaaa");
    Console.WriteLine("bbbbbb");
    Console.WriteLine("cccccc");
    Console.WriteLine($"{storage}");
}
catch (OverflowException o)
{
      //处理捕获的算术溢出异常。执行完毕后将向下执行,不会返回抛出异常位置处继续执行!
    Console.WriteLine($"{o.Message}"); ; 
}

Console.WriteLine("ddddddd");

抛出异常,导致有些语句无法运行,解决方案是写一个finally语句块,放到其中的语句总是运行。


Devide(2,0); // 没有写捕获异常的处理程序,程序将报错退出。
......

int Devide(int first, int second)
{
      int result = 0;
      try
      {
          result = first / devide; // 被除数为0,抛出devideByZeroException。
  
      } //没有匹配的catch语句块,
      finally
      {
            //首先运行finally块,再返回上一级搜索匹配的处理程序。
            Console.WriteLine("算术语句异常");
      }
}
    ```
posted @ 2021-02-07 11:43  葡式蛋挞  阅读(21)  评论(0)    收藏  举报