码迷,mamicode.com
首页 > 其他好文 > 详细

异常处理

时间:2019-06-07 00:34:02      阅读:96      评论:0      收藏:0      [点我收藏+]

标签:顺序   OLE   判断   程序   one   null   void   VID   参数   

异常处理

在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语句中
  • 应该尽量在上层捕获并处理异常(全局异常处理),过多的下层处理会有性能损失

异常处理

标签:顺序   OLE   判断   程序   one   null   void   VID   参数   

原文地址:https://www.cnblogs.com/home-wang/p/10972879.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!