zoukankan      html  css  js  c++  java
  • 异常处理

    异常处理

    在C#中,所有的异常都是使用一个异常类型的实例对象表示,都继承自System.Exception类型,或者直接使用System.Exception类型的实例对象;位于finally块中的代码可以保证不管代码是正常结束,还是进入异常处理代码块,其中的语句均会被执行,finally语句中放置资源回收的代码是一个不错的主意;BCL都提供了预定义的异常类供使用,其使用方式和应用级别的异常处理完全相同。

    异常类

    System.Exception类是所有异常类的基类,其中:

    • Message:只读字符串,此属性为当前的异常提供了描述性信息
    • InnerException:只读属性,值不为null,则可以通过它的值获取当前异常的异常实例;如果其值为null,则表示当前异常不是由其他异常引发的
    • StackTrace:只读字符串,描述了调用堆栈的内容,其中首先显示最近的方法调用

    为了区分系统级异常和应用级异常,BCL提供了两种直接继承自System.Exception的异常类型,System.SystemException和System.ApplicationException。因此我们编写的自定义异常应从ApplicationException继承。

    抛出异常

    public long Divide(int a, int b)
    {
        try
        {
            return a / b;
        }
        catch (System.DivideByZeroException e)
        {
            //抛出异常
            //如果有原始异常,推荐将原始异常传入
            throw new System.ArgumentException(“除数不能为0”, “b”, e);
        }
    }
    

    捕获异常

    处理异常时都按照从特定到最不特定(从具体到一般)的顺序对catch块中处理的异常进行排序,try/catch块有三种形式:try-catch、try-finally、try-catch-finally,不带catch或finally块的try语句将导致编译器错误。

    try {}  //可能引发异常的代码
    catch (System.ApplicationException e) {} //异常处理代码块,可以有多个
    catch (System.SystemException e) {}        //顺序从具体到一般
    finally {}  //不管是否发生异常,均会执行
    

    当异常发生后,CLR首先会判断当前引发的是何种异常类型,例如:是DivideByZeroException还是ArgumentException,然后以从上至下的顺序,搜索与当前执行语句(且和具体的异常类型)最匹配的catch块。搜索会从当前方法开始,寻找方法是否包括于一个try/catch块内,如果有,就对catch进行匹配,如果没有就定位到调用当前方法并继续寻找,一直向上层继续,直到找到为止。

    如果存在两个catch块,一个是捕获某个特定的异常,一个是捕获更加常规的异常,注意:

    • 捕获特定异常的匹配度要比捕获常规异常的匹配度高
    • 捕获特定类型的catch块和基类型的catch块同时存在,则前者要位于后者之前,否则无法通过编译
    class OneException : ApplicationException {}
    
    class Program
    {
        static void DoSomething()
        {
            throw new OneException();
        }
    
      static async Task Main(string[] args)
      {
        try
        {
            Program.DoSomething();
        }
        catch (OneException e)
        {
            //执行
            Console.WriteLine("OneException code");
        }
        catch (ApplicationException e)
        {
            //ApplicationException是OneException的基类,同时出现时必须放在它的后面,否则会编译错误
            Console.WriteLine("ApplicationException code");
        }
        catch (SystemException e)
        {
            Console.WriteLine("SystemException code");
        }
        finally
        {
            //执行
            Console.WriteLine("finally code");
        }
      }
    }
    

    一般来说,除非明确知道如何处理try块中可能引发的所有异常,或者catch块的末尾包括一条throw语句,否则请不要在catch块中指定Exception,

    自定义的异常

    自定义的异常应该从System.Application.Exception派生,创建时要注意:

    • 从System.Application.Exception和System.Exception派生
    • 使用Exception这个词作为自定义的异常名称为后缀
    • 至少提供三个公共构造函数(一个不包含参数的默认构造函数、一个可以包含异常消息的构造函数、一个可以包含异常消息,以及引发异常的异常引用的构造函数)

    异常处理方法

    • 尽量先由程序自动处理异常,若不能则考虑使用友好的提示告知用户,并根据等级记录日志
    • 限定异常范围,尽量缩小异常处理范围,如果只需要检测某一行代码,就不要把整段代码都放进try语句中
    • 应该尽量在上层捕获并处理异常(全局异常处理),过多的下层处理会有性能损失
  • 相关阅读:
    疫情环境下的网络学习笔记 python 5.8 数据库入门终章
    疫情环境下的网络学习笔记 python 5.7 navicat数据库,例题,sql注入
    疫情环境下的网络学习笔记 python 5.6 暂时看看
    疫情环境下的网络学习笔记 python 5.5 MYSql 表关系,外键
    疫情环境下的网络学习笔记 python 5.4 数据库基础
    疫情环境下的网络学习笔记 python 4.30 初识数据库
    疫情环境下的网络学习笔记 python 4.29 网络小项目
    XJOI 夏令营501-511测试11 游戏
    XJOI 夏令营501-511测试11 统计方案
    CF1197D Yet Another Subarray Problem
  • 原文地址:https://www.cnblogs.com/home-wang/p/10972879.html
Copyright © 2011-2022 走看看