C# 异常处理 详解

总目录


前言


一、异常

1、定义

异常是在程序执行期间出现的问题。
C# 中的异常是对程序运行时出现的特殊情况的一种响应,比如尝试除以零。

异常:程序员必须控制和解决的问题。程序可以正常的运行,但是在运行的过程中出现了问题,问题包括:非法数值,死循环,数组超出索引,访问空对象,格式化转换错误…等等,异常是程序员必须处理的。

异常具有以下属性:

  • 异常是最终全都派生自 System.Exception 的类型。
  • 在可能抛出异常的语句周围使用 try 代码块。
  • 在 try 代码块中出现异常后,控制流会跳转到调用堆栈中任意位置上的首个相关异常处理程序。 在 C# 中,catch 关键字用于定义异常处理程序。
  • 如果给定的异常没有对应的异常处理程序,那么程序会停止执行,并显示错误消息。

2、基本使用

C# 异常处理是建立在四个关键词之上的:try、catch、finally 和 throw。

  • try:try 代码段,表示尝试运行一段代码,如果出现异样,将控制权交给catch。try后可跟一个或多个 catch 块。
  • catch:程序通过异常处理程序捕获异常。catch 关键字表示异常的捕获。
  • finally:finally 块用于执行给定的语句,不管异常是否被抛出都会执行。如:打开一个文件,不管是否出现异常文件都要被关闭。
  • throw:当问题出现时,程序抛出一个异常。使用 throw 关键字来完成。

异常处理格式如下:

	try{// 引起异常的语句}catch( ExceptionName e1 ) //try后可以跟一个或多个catch{throw new Exception("****"); //使用throw 抛出异常信息}catch( ExceptionName e2 ){// 错误处理代码}finally //finally不是必须的,根据业务需要使用{// 要执行的语句 ,不论是否异常都会执行这里的代码}

3、异常类

  • System.ApplicationExceptionSystem.SystemException 类是派生于 System.Exception 类的异常类。
  • System.ApplicationException 类支持由应用程序生成的异常。所以程序员定义的异常都应派生自该类。
  • System.SystemException 类是所有预定义的系统异常的基类。

在这里插入图片描述

案例代码如下:

        public static void Division(int num1, int num2){var result = 0;try{result = num1 / num2;}catch (DivideByZeroException e){Console.WriteLine($"【异常信息】:{e.Message}");Console.WriteLine($"【异常代码行】:{e.StackTrace}");Console.WriteLine($"【异常所有信息】: {e}");    }finally{Console.WriteLine($"Result: {result}");}}static void Main(string[] args){Program.Division(18,0);Console.ReadLine();}

4、自定义异常

定义自己的异常。用户自定义的异常类是派生自 ApplicationException 类。

using System;
namespace UserDefinedException
{class TestTemperature{static void Main(string[] args){Temperature temp = new Temperature();try{temp.showTemp();}catch(TempIsZeroException e){Console.WriteLine("TempIsZeroException: {0}", e.Message);}Console.ReadKey();}}
}
public class TempIsZeroException: ApplicationException
{public TempIsZeroException(string message): base(message){}
}
public class Temperature
{int temperature = 0;public void showTemp(){if(temperature == 0){throw (new TempIsZeroException("Zero Temperature found"));}else{Console.WriteLine("Temperature: {0}", temperature);}}
}

二、异常处理

        static void Main(string[] args){Program.Division0(18,0);Console.Read();}public static void Division0(int num1, int num2){var result = num1 / num2;Console.WriteLine($"Result: {result}");}

在这里插入图片描述

这是一个存在异常情况的代码,当我们不使用try catch 来捕获异常的时候,运行该程序会直接显示异常,然后关闭程序。

1、不抛出异常

使用try catch 处理异常,程序内部处理掉,不使用 throw 抛出异常。

        static void Main(string[] args){Program.Division(18,0);Console.Read();}public static void Division(int num1, int num2){var result = 0;try{result = num1 / num2;}catch (Exception e){Console.WriteLine($"【异常信息】: {e}");}finally{Console.WriteLine($"Result: {result}");}}

运行结果:打印错误信息,程序不会因为异常而关闭。
在这里插入图片描述

某些场景下,我们需要保证用户的使用体验,选择不抛出异常,大多是上线后,这时基本没什么Bug了

2、抛出异常

使用try catch 处理异常,使用 throw 抛出异常。

        static void Main(string[] args){Program.Division(18,0);Console.Read();}public static void Division(int num1, int num2){var result = 0;try{result = num1 / num2;}catch (Exception e){Console.WriteLine($"【异常信息】: {e}");throw;}finally{Console.WriteLine($"Result: {result}");}}

运行结果:打印错误信息,程序会因为抛出的异常而关闭。

某些场景下,我们需要抛出异常。大多是开发过程中,通过抛出的异常,我们可以更好的定位和修复异常,完善我们开发的程序。

3、throw、throw ex、throw new Exception 的区别

在C#中引发异常的三种常见方法是throw、throw ex 和 throw new Exception(ex),尽管它们看起来很相似,但它们都有不同的行为和实例。

1. 案例

使用throw / throw ex / throw new Exception 抛出异常,然后使用try catch 捕获异常,查看三者抛出的异常信息有什么区别

  • 使用 throw 抛出异常
    在这里插入图片描述
    运行结果
    在这里插入图片描述
    使用throw 抛出的异常,再次被捕获的时候,会将错误信息定位在throw 的那一行,而非真正引发异常的 result=num1/num2 那一行。
    如果需要获取,真正的错误信息,就需要在catch中直接先写入日志,再抛出异常,这样有利于我们异常快速定位!

  • 使用throw ex 抛出异常
    在这里插入图片描述
    运行结果
    在这里插入图片描述
    使用throw ex 抛出的异常,再次被捕获的时候,会将错误信息定位在throw ex的那一行,而非真正引发异常的 result=num1/num2 那一行。
    如果需要获取,真正的错误信息,就需要在catch中直接先写入日志,再抛出异常,这样有利于我们异常快速定位!

  • 使用throw new Exception 抛出异常
    在这里插入图片描述
    运行结果
    在这里插入图片描述
    使用 throw new Exception 抛出的异常,再次被捕获的时候,会有相较于throw 和 throw ex 更为详细的异常信息(列出了导致异常的所有的信息)

2. 进一步 案例

  • 上面的案例仅仅是展示 使用三种形式抛出异常后 运行结果,那么在实际的开发过程中,有可能会出现try catch 嵌套多层的情况。
  • 多层try catch 嵌套的时候就需要注意 异常的追踪
  • 原则上尽量不要嵌套多层,如果嵌套了多层就需要了解这三种抛异常需要注意的点
    internal class Program{static void Main(string[] args){try{Program.Division2();}catch (Exception ex){Console.WriteLine($"【捕获抛出的异常】:{ex}");}Console.ReadLine();}public static void Division2(){try{Program.Division(18, 0);}catch (Exception ex){throw;//throw ex;//throw new Exception("计算异常", ex);}}public static void Division(int num1, int num2){var result = 0;try{result = num1 / num2;}catch (Exception ex){throw;//throw ex;//throw new Exception("计算异常",ex);}}}
  • 案例代码
    在这里插入图片描述

  • 使用 throw 抛异常运行的结果
    在这里插入图片描述

  • 使用throw ex 抛异常运行的结果
    在这里插入图片描述
    注意:这里通过throw ex 抛出异常,重置堆栈跟踪,将原本行号51 的错误信息,重置到了行号 35,不利于我们定位异常信息。

  • 使用throw new Exception 抛异常的结果
    在这里插入图片描述
    仍旧是具有最全面的异常信息

3. 小结

三者的区别点:

  • 1、堆栈跟踪

    • throw:保留原始堆栈跟踪,提供有关异常来源的完整信息。
    • throw ex:重置堆栈跟踪,这可能会使调试异常的根本原因发生改变。
    • throw new Exception:为新的异常消息提供其他上下文,同时将原始异常保留为内部异常。
  • 2、应用场景

    • throw:需维护原始异常上下文和堆栈跟踪时,使用该方法。
    • throw ex:该方法谨慎,如需使用,应在重新引发异常之前向异常添加其他信息。
    • throw new Exception:如果需要往异常添加更多上下文,同时保留原始异常详细信息,使用该方式。
  • 3、建议

    • 慎用 throw ex 抛出异常
    • 建议使用throw ex 或者 throw new Exception,使用throw new Exception 内存占用会大些但是信息更全面

结语

回到目录页: C# 知识汇总
希望以上内容可以帮助到大家,如文中有不对之处,还请批评指正。


参考资料:
C#文档 - 异常和异常处理
C#异常处理throw、throw ex、throw new Exception 区别
C# 异常处理

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

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

相关文章

类OCSP靶场-Kioptrix系列-Kioptrix Level 2

一、前情提要 二、实战打靶 1. 信息收集 1.1. 主机发现 1.2. 端口扫描 1.3.目录遍历 2.漏洞发现 2.1. 登录框测试 2.2. 发现命令执行 2.3 构造命令执行利用payload 3.提权 3.1. 搜索提权exp 3.2. 查看exp信息 3.3. Privilege Escalation的exp利用 exp_9542 一、前…

μC/OS-Ⅱ源码学习(6)---事件标志组

快速回顾 μC/OS-Ⅱ中的多任务 μC/OS-Ⅱ源码学习(1)---多任务系统的实现 μC/OS-Ⅱ源码学习(2)---多任务系统的实现(下) μC/OS-Ⅱ源码学习(3)---事件模型 μC/OS-Ⅱ源码学习(4)---信号量 μC/OS-Ⅱ源码学习(5)---消息队列 本文进一步解析事件模型中,事件标志…

学习maven(maven 项目模块化,继承,聚合)

前言 本篇博客的核心:理解maven 项目模块化,继承,聚合 的含义 maven 项目模块化 含义 maven项目模块化:使用maven 构建项目,管理项目的方式,我们可以将maven项目根据内在的关系拆分成很多个小项目【模块】…

电工电子技术实验:电压比较器及其应用电路

实验目的 1.了解电压比较器与运算放大器的性能区别; 2.掌握电压比较器的结构及特点; 3.掌握电压比较器电压传输特性的测试方法; 4.学习比较器在电路设计中的应用 实验原理 电压比较器是一…

3D相框案例讲解(详细)

前言 通过现阶段的学习,我们已经掌握了HTML,CSS和JS部分的相关知识点,现在让我们通过一篇案例,来巩固我们近期所学的知识点。 详细视频讲解戳这里 任务一 了解目标案例样式 1.1了解案例 3D相框 1.2 分析案例 首先我们看到一个…

C/C++代码性能优化技巧的书籍及资料

使用C/C开发的场景,大多对代码的执行的速度,实时性有较高的要求,像嵌入式系统的开发,资源还受限。在算力存储空间有限的MCU上写出简洁又高效的代码实际是一种艺术。软件工程师在代码设计上的这种差距,会反映在产品的性…

JAVA:建造者模式(Builder Pattern)的技术指南

1、简述 建造者模式(Builder Pattern)是一种创建型设计模式,它通过将对象的构造过程与表示分离,使得相同的构造过程可以创建不同的表示。建造者模式尤其适用于创建复杂对象的场景。 设计模式样例:https://gitee.com/lhdxhl/design-pattern-example.git 本文将详细介绍建…

软件集成测试内容和作用简析

在现代软件开发过程中,软件集成测试作为关键的一环,日益受到重视。特别是随着信息技术的快速发展,各类软件系统日益庞大复杂,如何确保系统不同模块的顺畅合作,成为了每个项目成功的重要基础。集成测试是指在软件开发过…

Windows 环境实战开源项目GFPGAN 教程

GFPGAN GFPGAN(Generative Facial Prior-GAN)是由腾讯ARC(Applied Research Center)开发的一种实用的真实世界人脸修复算法。它专门设计用于人脸图像的生成和优化,尤其在低质量人脸图像的超分辨率恢复方面表现出色。以…

ctfshow xss

1.web316 看的wp 先在服务器上写一个php文件 <?php$cookie $_GET[cookie];$time date(Y-m-d h:i:s, time());$log fopen("cookie.txt", "a");fwrite($log,$time.: . $cookie . "\n");fclose($log); ?> 获取cookie的值&#xff…

25. 深浅拷贝

一、什么是浅拷贝 只对对象的最顶层进行的拷贝称为 浅拷贝。我们可以用 copy 模块中的 copy() 方法实现浅拷贝。 import copya [11, 22, 33] b [44, 55, 66] c [a, b] d copy.copy(c)print(f"c: {c}") print(f"d: {d}") print(f"c d: {c d}&q…

MySQL追梦旅途之性能优化

1、索引优化 索引可以显著加速查询操作&#xff0c;但过多或不适当的索引也会带来负面影响&#xff08;如增加写入开销&#xff09;。因此&#xff0c;选择合适的索引至关重要。 创建索引&#xff1a; 为经常用于WHERE子句、JOIN条件和ORDER BY排序的列创建索引。 CREATE I…

Liveweb视频汇聚平台支持WebRTC协议赋能H.265视频流畅传输

随着科技的飞速发展和网络技术的不断革新&#xff0c;视频监控已经广泛应用于社会各个领域&#xff0c;成为现代安全管理的重要组成部分。在视频监控领域&#xff0c;视频编码技术的选择尤为重要&#xff0c;它不仅关系到视频的质量&#xff0c;还直接影响到视频的传输效率和兼…

【超详细实战攻略】Jmeter逻辑控制器中if控制器、模块控制器、测试片段的使用方法

【超详细实战攻略】Jmeter逻辑控制器中if控制器、模块控制器、测试片段的使用方法 1 搭建测试对象1.1 禅道下载1.2 禅道安装1.3 运行禅道1.4 接口查看1.5 接口选择 2 Jmeter前置操作2.1 创建Jmeter线程组2.2 创建信息头管理器和请求默认值2.3 添加获取token接口2.4 添加监听器 …

我在广州学 Mysql 系列之 数据类型和运算符详解

ℹ️大家好&#xff0c;我是&#x1f606;练小杰&#xff0c;今天主要学习 Mysql的数据类型以及运算符操作~~ 上周五学习了“Mysql 系列之 数据“表”的基本操作”~ 想要了解更多&#x1f236;️MYSQL 数据库的命令行总结&#xff01;&#xff01;&#xff01; “我是你的敌人,…

如何高效获取Twitter数据:Apify平台上的推特数据采集解决方案

引言 在数据分析和市场研究领域&#xff0c;Twitter&#xff08;现在的X&#xff09;数据一直是重要的信息来源。但是&#xff0c;自从Twitter更改API定价策略后&#xff0c;获取数据的成本大幅提升。本文将介绍一个经济实惠的替代方案。 为什么需要Twitter数据&#xff1f; …

大模型学习笔记------SAM模型详解与思考

大模型学习笔记------SAM模型详解与思考 1、SAM框架概述2、Segment Anything Task3、Segment Anything Model SAM模型是Meta 提出的分割一切模型&#xff08;Segment Anything Model&#xff0c;SAM&#xff09;突破了分割界限&#xff0c;极大地促进了计算机视觉基础模型的发展…

Unity3D仿星露谷物语开发2之工程初始化

1、依赖包安装 进入【Window -> Package Manager】 安装如下插件&#xff1a; 1&#xff09;Cinemachine 它是一套专门控制Unity Camera的模块&#xff0c;适用于各种游戏场景中物体的移动变化&#xff0c;解决了许多关于摄像机间的复杂控制&#xff0c;混合&#xff0c…

[论文阅读] |智能体长期记忆与反思

写在前面&#xff1a;10月份的时候&#xff0c;联发科天玑9400发布&#xff0c;搭载这款旗舰 5G 智能体 AI 芯片的荣耀MagicOS9.0实现了一句话让手机自动操作美团点咖啡。很快商场实体店里便能看到很多品牌手机已经升级为智能体语音助手。下一步&#xff0c;这些智能体或许便能…

数据结构之线性表1

2.1 线性表的定义和基本操作 1.线性结构的特点是&#xff1a;在数据元素的非空有限集中&#xff0c; &#xff08;1&#xff09;存在惟一的一个被称做“第一个”的数据元素&#xff1b; &#xff08;2&#xff09; 存在惟一的一个被称做“最后一个”的数据元素&#xff1b; &a…