Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 135938|回复: 0

详解C#异常处理

[复制链接]
  • TA的每日心情
    奋斗
    2024-4-6 11:05
  • 签到天数: 748 天

    [LV.9]以坛为家II

    2034

    主题

    2092

    帖子

    70万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    705612
    发表于 2021-4-7 15:14:22 | 显示全部楼层 |阅读模式

      一、程序运行时产生的错误通过使用一种称为异常(Exception)的机制在程序中传递,通过异常处理(Exception Handling)有助于处理程序运行过程中发生的意外或异常情况;异常可由CLR和客户端代码抛出(Throw),抛出的异常会在调用堆栈中传递,直到遇到可以捕获该异常的语句进行处理并中止传递,未捕获的异常会由系统终止进程并由系统的通用异常处理程序处理,通常会显示一个包含异常信息的对话框;

      1.异常是通过一个特殊类型的对象进行传递的,其基类是位于命名空间System中的类Exception,自定义的异常类型必须继承自该类并以Exception结尾,异常对象中包含描述异常的自定义数据:

    public class MyException : Exception
    {
        public string MyInfo;
    }

      ※基类Exception中的属性Message包含抛出异常的原因,属性StackTrace包含抛出异常时调用堆栈上方法的名称、位置和行号,此属性由CLR在throw语句的调用位置自动创建,重写的ToString()方法会打印异常的类型名称、属性Message和StackTrace,只读属性InnerException通常用来保存抛出异常的原始异常,需要在新创建异常对象时通过构造函数传入;

      ※完整的自定义异常类型应添加可序列化特性Serializable并至少声明四个构造函数:默认构造函数、设置Message属性的构造函数、设置Message和InnerException属性的构造函数、用于序列化异常的构造函数:

    using System.Runtime.Serialization;
    [Serializable]
    public class MyException : Exception
    {
        public MyException() : base() { }
        public MyException(string message) : base(message) { }
        public MyException(string message, Exception inner) : base(message, inner) { }
        //当异常从远程处理服务器传播到客户端时,需要该构造函数进行序列化
        protected MyException(SerializationInfo info, StreamingContext context) : base(info, context) { }
    }

      2.抛出异常时会涉及异常类型对象的实例化和初始化,并通过关键字throw抛出该异常:

    public static void MyFunc()
    {
        throw new MyException { MyInfo = "My Exception Throw." };
    }

      3.使用try语句块对可能抛出异常的代码进行包裹,使用关联的catch语句块处理抛出的异常,使用关联的finally语句块声明无论是否抛出异常都会执行的语句,例如释放try语句块中分配的非托管资源;完整的异常处理语句需要包含一个try语句块和:一个或多个catch语句块、一个finally语句块或二者都有,即try-catch-(finally)、try-finally;

      ※一个try语句块可以包含多个catch语句块,catch语句块用来指定要捕获异常的类型,也被称为异常筛选器,catch语句也可以不指定筛选器,此时默认将基类Object作为筛选器,一般情况下必须指定筛选器且不要直接指定基类Exception作为筛选器,除非了解可能抛出的所有类型的异常或在catch语句块末尾使用throw重新抛出该异常(此时将调用rethrow指令);catch语句应该在理解异常抛出的原因并可以实现特定的恢复时才使用,也可以用来进行部分处理并重新抛出或抛出一个更加具体的异常;catch语句块应该按照派生程度由高到底的顺序声明:
    t

    ry
    {
        MyFunc();
    }
    catch (MyException e) //可以捕获MeException类型的异常,如果不使用异常对象,变量e可以省略
    {
        Console.WriteLine("MyException Throw:" + e.MyInfo);
        //throw new MyException { MyInfo = "Detailed Information." };
    }
    catch (Exception e) //可以捕获所有类型的异常
    {
        Console.WriteLine("Unkown Exception:" + e);
        throw; //只有在catch语句块中可以这么使用
    }
    //catch //通常用于捕获非CLS异常
    //{
    //}
    finally
    {
        //do…
    }

      4.抛出异常时,CLR会在调用堆栈中按顺序搜索当前异常对象所兼容的异常筛选器(当前类型或其基类),当找到第一个兼容的异常筛选器后不再搜索其它的异常筛选器(因此应该将派生程度最高的catch块放在最前),此时会按照原调用堆栈的顺序执行finally语句块,然后调用捕获到异常的catch语句块,然后调用其finally语句块,最后将控制流传递给该语句块的下一语句继续执行;

      ※如果抛出的异常在调用堆栈中没有找到兼容的异常筛选器,会出现以下三种情况:
      1.如果异常在析构函数中抛出,则将中止该析构函数,并调用基类析构函数(如果有);
      2.如果调用堆栈中包含静态构造函数或静态字段初始化,则将抛出异常TypeInitializationException,并将原异常分配给其属性InnerException;且在当前应用的生命周期内CLR不会再次调用该函数,未执行的代码块将永远不会执行;
      3.如果异常到达线程的开头,则将终止该线程,并由系统终止进程并处理;


    如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的认可是我写作的最大动力!

    作者:Minotauros
    出处:https://www.cnblogs.com/minotauros/

    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-4-28 10:18 , Processed in 0.071729 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表