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

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

  1. public class MyException : Exception
  2. {
  3. public string MyInfo;
  4. }

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

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

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

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

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

  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

  1. ry
  2. {
  3. MyFunc();
  4. }
  5. catch (MyException e) //可以捕获MeException类型的异常,如果不使用异常对象,变量e可以省略
  6. {
  7. Console.WriteLine("MyException Throw:" + e.MyInfo);
  8. //throw new MyException { MyInfo = "Detailed Information." };
  9. }
  10. catch (Exception e) //可以捕获所有类型的异常
  11. {
  12. Console.WriteLine("Unkown Exception:" + e);
  13. throw; //只有在catch语句块中可以这么使用
  14. }
  15. //catch //通常用于捕获非CLS异常
  16. //{
  17. //}
  18. finally
  19. {
  20. //do…
  21. }

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

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


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

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

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

详解C#异常处理的更多相关文章

  1. Reactor详解之:异常处理

    目录 简介 Reactor的异常一般处理方法 各种异常处理方式详解 Static Fallback Value Fallback Method Dynamic Fallback Value Catch ...

  2. 【WebApi系列】详解WebApi如何传递参数

    WebApi系列文章 [01]浅谈HTTP在WebApi开发中的运用 [02]聊聊WebApi体系结构 [03]详解WebApi参数的传递 [04]详解WebApi测试和PostMan [05]浅谈W ...

  3. Spring Boot异常处理详解

    在Spring MVC异常处理详解中,介绍了Spring MVC的异常处理体系,本文将讲解在此基础上Spring Boot为我们做了哪些工作.下图列出了Spring Boot中跟MVC异常处理相关的类 ...

  4. SpringMVC异常处理机制详解[附带源码分析]

    目录 前言 重要接口和类介绍 HandlerExceptionResolver接口 AbstractHandlerExceptionResolver抽象类 AbstractHandlerMethodE ...

  5. 异常处理与MiniDump详解(4) MiniDump

    http://blog.csdn.net/vagrxie/article/details/4398721 异常处理与MiniDump详解(4) MiniDump 分类:             [Wi ...

  6. 异常处理与MiniDump详解(转)

    一.   综述 总算讲到MiniDump了. Dump有多有用我都无法尽数,基本上属于定位错误修复BUG的倚天剑.(日志可以算是屠龙刀)这些都是对于那些不是必出的BUG,放在外面运行的时候出现的BUG ...

  7. Linux内核异常处理体系结构详解(一)【转】

    转自:http://www.techbulo.com/1841.html 2015年11月30日 ⁄ 基础知识 ⁄ 共 6653字 ⁄ 字号 小 中 大 ⁄ Linux内核异常处理体系结构详解(一)已 ...

  8. 异常处理器详解 Java多线程异常处理机制 多线程中篇(四)

    在Thread中有异常处理器相关的方法 在ThreadGroup中也有相关的异常处理方法 示例 未检查异常 对于未检查异常,将会直接宕掉,主线程则继续运行,程序会继续运行 在主线程中能不能捕获呢? 我 ...

  9. 异常处理与MiniDump详解(2) 智能指针与C++异常

    write by 九天雁翎(JTianLing) -- blog.csdn.net/vagrxie 讨论新闻组及文件 一.   综述 <异常处理与MiniDump详解(1) C++异常>稍 ...

随机推荐

  1. github管理项目

    1.在GitHub上创建一个项目,然后拷贝git地址. 2.在本地打开GIT CMD,然后建立一个文件夹,输入git clone 上面拷贝的git地址. 3.文件夹下会多出一个以你创建的项目名字的文件 ...

  2. Debian 使用 Samba 服务为 Windows 客户端和 Linux 客户端提供文件服务

    1 目标 1.1 主机采用 Debian,为 Windows 和 Liunx 客户端提供文件存取服务 1.2 Windows 采用 GB2312 编码,Linux 采用 UTF-8 编码,要求中文不出 ...

  3. centos7 制作yum源

    一.依赖 1.rsync yum install -y rsync xinetd 2.nginx,这个就不多说了 二.建立目录 mkdir -p /data/yum_source/nginx/html ...

  4. Spring 的配置详解

    Bean元素 Spring创建对象的方式 (1)空参构造方式 (2)静态工厂(了解) (3)实例工厂方式 Bean元素进阶 (1)scope属性 a.singleton (2)生命周期属性 Sprin ...

  5. Linux 第八天

    4.源码包和rpm包的区别 1)区别 安装前:概念上的区别 安装后:安装位置不同 2)安装位置 rpm包安装位置 Rpm包默认安装路径 /etc/ 配置文件安装目录 /usr/bin/ 可执行的命令安 ...

  6. 自动化部署shell

    yum install curl policycoreutils openssh-server openssh-clients postfix [root@linux-node2 ~]# yum in ...

  7. docker安装redis 指定配置文件且设置了密码

    ---------首先,所有docker的命令,都可以用 docker help 来查询,这个挺好的,我反正记不住辣么多命令呀.   1.直接pull 官方镜像吧.没啥说的,这样方便省事.如果你非要用 ...

  8. 阅读笔记4 我是一只IT小小鸟

    经过一周连续三四天八小时以上坐在电脑前敲代码的“折磨”,去看看其他经受这些折磨的人的感受.这次读书笔记变成了逗比风,因为前几周认认真真记下书里写的重点内容,然后把学习的内容认真的记录下来的笔记被老师助 ...

  9. git dev 分支merge到master

    code reviewer之后,需要把dev分支的代码merge到master分支.通过在azkaban的服务器上git pull,最终将代码上线. git dev 分支merge到master # ...

  10. centos7图形界面

    安装centOS7服务器版本,系统默认是不会安装GUI的图形界面程序,这个需要手动安装CentOS7 Gnome GUI包. 安装GUI包.开机自动启动图形界面.重启 # yum groupinsta ...