C# 图解教程 第5版 —— 第23章 异常

文章目录

    • 23.1 什么是异常
    • 23.2 try 语句
    • 23.3 异常类
    • 23.4 catch 子句
    • 23.5 异常过滤器
    • 23.6 catch 子句段
    • 23.7 finally 块
    • 23.8 为异常寻找处理程序
    • 23.9 进一步搜索
      • 23.9.1 一般法则
      • 23.9.2 搜索调用栈的示例(*)
    • 23.10 抛出异常
    • 23.11 不带异常对象的抛出
    • 23.12 throw 表达式

23.1 什么是异常

​ 异常是程序中的运行时错误,它违反了系统约束或应用程序约束,或是正常操作时不会发生的状况。如果程序没有提供处理异常的代码,系统会挂起这个程序。例如,下面的代码在试图用 0 除一个数时抛出一个异常:

image-20240113130921192 image-20240113130931943

​ 在没有异常处理程序的情况下,应用程序将停止(或者崩溃),并向用户显示非常不友好的错误消息。异常处理的目标是通过以下操作来响应异常:

  1. 在有限的几种情况下采取纠正措施,让应用程序继续运行。
  2. 记录有关异常的信息,以便开发团队可以解决该问题。
  3. 清理任何外部资源,例如可能保持打开的数据库连接。
  4. 向用户显示友好的信息。

23.2 try 语句

​ try 语句用来指明为避免出现异常而被保护的代码段,并在发生异常时提供代码处理。其包含 3 个部分组成:

  1. try 块。
  2. catch 子句。
  3. finally 块。
image-20240113131311982
图23.1 try 语句的结构

处理异常

​ 将上述代码段放在一个 try 块中,并提供一个简单的 catch 子句来捕获并处理异常。

image-20240113131404143 image-20240113131414697

23.3 异常类

​ BCL 定义了许多异常类,每一个类代表一种指定的异常类型。当一个异常发生时,CLR 创建该类型的异常对象并寻找适当的 catch 子句以处理它。

​ 所有异常类都派生自 System.Exception 类,System.Exception 类派生自 System.Object 类。

image-20240113131616192
图23.2 异常层次的结构

​ 异常对象含有只读属性,该属性提供有助于调试应用程序的异常信息。

表23.1 异常对象的一部分属性
image-20240113131830423

23.4 catch 子句

​ catch 子句处理异常,有如下 4 种形式:

image-20240113131923698
图23.3 catch 子句的 4 种形式
  • 一般 catch 子句(形式 1):能接受任何异常,但不确定引发异常的异常类型,只能进行普通处理和清理。
  • 特定 catch 子句(形式 2):把一个异常类的名称作为参数,匹配指定类或派生自它的异常类的异常。
  • 带对象的特定 catch 子句(形式 3、4):提供的异常信息最多,可以在 catch 子句块内部访问异常变量的属性,以获取异常的详细信息。
image-20240113132339051

23.5 异常过滤器

​ 形式 4 的 catch 子句是在 C# 6.0 中添加的,相较于形式 3,异常对象还需满足特定条件,该条件被称为过滤器。这允许程序员编写更小、更专一的异常处理程序,而无需再单个处理程序中包含大量 if 语句。

image-20240113132555826

​ 有关 when 子句的重要特征如下:

  • 必须包含谓词表达式(返回值为 true 或 false)。
  • 不能是异步的。
  • 不应使用任何需要长时间运行的操作。
  • 谓词表达式中发生的异常会被忽略。

23.6 catch 子句段

​ catch 子句段可以包含多个 catch 子句。

image-20240113133131889
图23.4 try 语句的 catch 子句段结构

​ 当发生异常时,系统按顺序搜索 catch 子句的列表,第一个匹配该异常对象类型的 catch 子句被执行。

  • catch 子句必须以特定顺序排列。最特定的异常类型排第一,最普通的类型排最后。
  • 如果有一个一般 catch 子句,则必须放在最后一个。
  • 不鼓励使用一般 catch 子句,因为它允许程序继续执行从而隐藏了特定错误,让程序处于一种位置的状态。

23.7 finally 块

​ 如果程序的控制流进入了带 finally 块的 try 语句,那么 finally 始终会被执行。

image-20240113133444181
图23.5 finally 块的执行

​ 即是 try 块中有 return 语句,或在 catch 块中抛出一个异常,finally 块也总是会在返回到调用代码之前执行。

image-20240113133744787

​ 上述代码在 inVal 值为 5 时也会打印 finally 块中的语句。

image-20240113133821319

23.8 为异常寻找处理程序

​ 当程序抛出异常时,系统查看该程序是否提供了异常处理程序,具体流程如下:

  • 如果在 try 块内发生了异常,系统会查看是否有任何一个 catch 子句能处理该异常。
  • 如果找到了适当的 catch 子句:
    1. 该 catch 子句被执行。
    2. 如果有 finally 块,那么它被执行;否则,继续在最后一个 catch 子句之后执行。
image-20240113134246204
图23.6 在当前 try 语句中有处理程序的异常

23.9 进一步搜索

​ 如果异常在一个没有被 try 语句保护的代码段抛出,或者如果 try 语句没有匹配的异常处理程序,系统将不得不进一步寻找匹配的处理程序。即,按顺序搜索调用栈,查看是否存在带匹配的处理程序的封装 try 块。

​ 如果异常发生在 Method2 内的 try 块内部,系统会执行如下操作:

  1. 首先查看 Method2 是否有能处理该异常的异常处理程序:
    • 如果有,Method2 处理,程序继续执行。
    • 否则,系统沿着调用栈找到 Method1,搜寻适当的处理程序。
  2. 如果 Method1 有一个适当的 catch 子句,那么系统将:
    • 回到栈顶,即 Method2 处。
    • 执行 Method2 的 finally 块,并将 Method2 弹出栈。
    • 执行 Method1 的 catch 子句和 finally 块。
  3. 如果 Method1 没有适当的 catch 子句,系统继续搜索调用栈。
image-20240113134534938
图23.7 搜索调用栈

23.9.1 一般法则

image-20240113134928143
图23.8 处理异常的一般法则

23.9.2 搜索调用栈的示例(*)

23.10 抛出异常

​ 使用 throw 语句使代码显示抛出异常,throw 语句的语法如下:

image-20240113135129478

​ 下面的代码在 try 块中进行参数 null 检查,创建并抛出 ArgumentNullException 异常。该实例在 catch 语句中被捕获,错误被打印出来。

image-20240113135200880 image-20240113135423860

23.11 不带异常对象的抛出

​ throw 语句可以在 catch 块内部不带异常对象使用。

  • 该形式重新抛出当前异常,系统会继续搜索,为该异常寻找另外的处理程序。
  • 这种形式只能用在 catch 语句内部。
image-20240113135559476 image-20240113135607676

23.12 throw 表达式

​ 代码中有些地方不允许使用语句,而只能使用表达式。C# 7.0 后,可以在只能应用表达式的地方使用 throw 表达式,其语法和 throw 语句相同。

image-20240113135912305 image-20240113135925872

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/630100.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LTD营销枢纽(乐通达)成为杭州市中小企业数字化转型遴选服务商

为推进国家中小企业数字化转型城市试点建设,赋能中小企业信息化、智能化、新型工业化能力水平提升,杭州市经信局公开招募了具备高质量服务能力的中小企业数字化转型服务商。经过公开征集、专家评审等多个环节,LTD营销枢纽凭借其在数字化转型领…

东北编程语言???

在GitHub闲逛,偶然发现了东北编程语言: 东北编程语言是由Zhanyong Wan创造的,它使用东北方言词汇作为基本关键字。这种编程语言的特点是简单易懂,适合小学文化程度的人学习,并且易于阅读、编写和记忆。它的语法与其他编…

Jetbrains ai assistant激活后仍无法使用,怎么回事?

用正式的ai assistant激活码激活后仍然无法使用 首先获取了ai assistant激活码,激活后如下 地址:https://web.52shizhan.cn 上图是已经激活成功了,但是在右侧这里打开ai assistant不可用 点击开始使用ai assistant 出错 以上是用了ai as…

java日志框架总结

一、日志框架简单分类介绍 java常用的日志框架、可以分为两组: 1、JCL、JUL、Log4j; 2、SLF4J、Log4j2、Logback; 其中第一组是比较早期的日志实现框架,JCL并不是具体的日志实现框架,JCL其实是定义了一…

运动模型非线性测量非线性扩展卡尔曼跟踪融合滤波算法(Matlab仿真)

卡尔曼滤波的原理和理论在CSDN已有很多文章,这里不再赘述,仅分享个人的理解和Matlab仿真代码。 之前的博文运动模型非线性扩展卡尔曼跟踪融合滤波算法(Matlab仿真)-CSDN博客使用扩展卡尔曼滤波算法将非线性的运动模型线性化&#…

我的年终总结2023

As a DBA 从2023年初开始,我就给自己定下了23年的主要任务——学习PostgreSQL数据库。虽然没有定下细致的计划,但总体的目标是把PG的一些基础知识学完。后来发现我想简单了,学习PG的成本比我想象的多的多,导致23年这个目标没有完…

葡萄酒术语“干”是什么意思呢?

一个初学品酒的人常常会感到力不从心,有如此多的术语,如甜、干、单宁、酒体等等,很容易让人迷失。嗯,就像情人眼里出西施一样,“好酒”因人而异。虽然品尝各种不同的葡萄酒是了解你喜欢什么的最好方法,但我…

3D渲染农场的优势体现在哪里?点进来,CG Magic小编告诉您!

目前,渲染的涉及也是越来越广的,无论是通过本地渲染还是云渲染,都是为了3D渲染效率更高。 渲染农场工作原理就是提升制作效率与降低成本的利器。无论大型制作公司还是小型工作室,甚至是个人用户,都会借助于3d渲染农场…

LLM:Scaling Laws for Neural Language Models (上)

论文:https://arxiv.org/pdf/2001.08361.pdf 发表:2020 摘要1:损失与模型大小、数据集大小以及训练所用计算量成比例,其中一些趋势跨越了七个量级以上。 2:网络宽度或深度等其他架构细节在很大范围内影响较小。3&…

探索Python数据结构与算法:解锁编程的无限可能

文章目录 一、引言1.1 数据结构与算法对于编程的重要性1.2 Python作为实现数据结构与算法的强大工具 二、列表和元组2.1 列表:创建列表、索引、切片和常用操作2.2 元组:不可变序列的特性和使用场景 三、字符串操作和正则表达式3.1 字符串的常见操作和方法…

windows编译TensorFlowServing

概述 整个编译打包过程的总体思路,是参照在linux下的编译流程,配置环境,执行编译命令,根据编译器/链接器反馈的错误,修改相应的源码或者相关库文件的存放路径,编译出windows平台下静态库和二进制执行文件。…

BuildRoot配置RTL8822CE WIFIBT模块(WIFI部分)

TinkerBoard2主板自带的无线模块为RTL8822CE,PCIe接口 之前在风火轮下载的Linux源码编译出来的BuildRoot根文件系统没有相关的驱动文件 [rootrk3399:/]# find . -name *.ko [rootrk3399:/]# lsmod Module Size Used by Not tainted [rootrk33…

Dicom Tag: Image Position,Image Orientation和Patient Position

文章目录 Image Position,Image Orientation和Patient PositionImage Position (0020,0032):Image Orientation (0020,0037):Patient Position(0018,5100): Image Position,Image Orientation和Patient Position 在DICOM图像中,I…

栈(顺序存储、链式存储)

栈的定义 栈(Stack)是只允许在一端进行插入或删除操作的线性表 栈的操作特性是后进先出LIFO(Last In First Out) 顺序存储 链式存储

三款非常实用的图片转换格式工具

BMP是一种常见的位图图像格式,而JPG则是互联网上广泛使用的图像格式。有时,为了满足特定的需求或更好的兼容性,我们需要将BMP格式转换为JPG格式。今天,我们将为您推荐三款实用的软件,帮助您轻松完成这一转换。 水印云…

QT 原生布局和QML的区别

一、QML 与 Qt Quick的区别 1.1 从概念上区分 为了更精确地对两者进行说明,先看助手对 QML 的描述: QML is a user interface specification and programming language. QML 是一种用户界面规范和标记语言,允许开发人员和设计师创建高性能、流…

端智能在大众点评搜索重排序的应用实践

1 引言 随着大数据、人工智能等信息技术的快速发展,云计算已经无法满足特定场景对数据隐私、高实时性的要求。借鉴边缘计算的思想,在终端部署 AI 能力逐渐步入大众的视野,“端智能”的概念应运而生。相比于传统的云计算,在智能手…

【Maven】008-Maven 私服搭建与使用

【Maven】008-Maven 私服搭建与使用 文章目录 【Maven】008-Maven 私服搭建与使用一、概述1、简介2、建立私服后依赖查找和下载逻辑第一步:请求本地仓库第二步:请求 Maven 私服第三步:请求外部远程仓库(远程中央仓库等&#xff09…

动态路由协议

一、动态路由协议 动态路由协议,用在多个 Router 之间定期的、自动的、互相交换 Routes(路由信息,包含了网段信息、可达性信息、路径信息等),动态生成 Routing Table Entries,并最终达到全网的路由收敛&am…

近4w字吐血整理!只要你认真看完【C++编程核心知识】分分钟吊打面试官(包含:内存、函数、引用、类与对象、文件操作)

🌈个人主页:godspeed_lucip 🔥 系列专栏:C从基础到进阶 🏆🏆关注博主,随时获取更多关于C的优质内容!🏆🏆 C核心编程🌏1 内存分区模型&#x1f384…