【C# 基础精讲】异常的类型和处理方法

在这里插入图片描述

异常(Exception)是在程序执行过程中发生的意外或异常情况,例如除零错误、空引用访问、文件不存在等。在C#及其他编程语言中,异常处理是一种重要的机制,用于捕获和处理程序运行时可能出现的错误,以保证程序的健壮性和稳定性。本文将详细介绍C#中的异常类型、异常处理机制以及最佳实践。

1. 异常类型

在C#中,异常分为两种类型:系统异常和自定义异常。

1.1 系统异常

系统异常是由.NET Framework或C#标准库引发的异常。它们是一些常见的运行时错误,如除以零、空引用访问、数组越界等。以下是一些常见的系统异常:

  • ArithmeticException:算术异常,如除以零。
  • NullReferenceException:空引用异常,当试图在引用为null的对象上调用方法或访问属性时引发。
  • IndexOutOfRangeException:索引越界异常,当数组或集合的索引超出范围时引发。
  • InvalidOperationException:无效操作异常,当执行的操作无效或不合理时引发,如集合为空时调用Remove方法。

1.2 自定义异常

除了系统异常,您还可以根据需要创建自定义异常类,以便在特定情况下引发并捕获异常。自定义异常类通常是从Exception类派生而来,您可以为其添加自定义的属性和方法。

class MyCustomException : Exception
{public MyCustomException(string message) : base(message){}
}

在程序中,您可以使用throw关键字来引发异常:

if (someCondition)
{throw new MyCustomException("This is a custom exception.");
}

2. 异常处理

异常处理是指在程序中检测、捕获和处理异常的过程,以防止程序在遇到错误时崩溃或产生不受控制的行为。在C#中,异常处理主要通过trycatchfinallythrow等关键字来实现。

2.1 try-catch 块

try-catch块用于捕获并处理异常。在try块中编写可能引发异常的代码,然后使用一个或多个catch块来捕获不同类型的异常并进行处理。

try
{// 可能引发异常的代码
}
catch (DivideByZeroException ex)
{Console.WriteLine("除以零错误:" + ex.Message);
}
catch (Exception ex)
{Console.WriteLine("发生异常:" + ex.Message);
}

在上述示例中,DivideByZeroException是系统异常的一种,catch块捕获并处理了除以零错误。第二个catch块用于捕获其他类型的异常。

2.2 finally 块

finally块用于在无论是否发生异常的情况下都会执行的代码。通常在finally块中进行清理操作,如关闭文件、释放资源等。

try
{// 可能引发异常的代码
}
catch (Exception ex)
{Console.WriteLine("发生异常:" + ex.Message);
}
finally
{// 清理操作,不管是否发生异常都会执行
}

2.3 throw 关键字

throw关键字用于手动引发异常,您可以使用系统异常类或自定义异常类来引发异常。

if (someCondition)
{throw new MyCustomException("This is a custom exception.");
}

2.4 使用 using 语句处理资源

C#中的using语句可用于确保在使用完资源后正确释放它们,以避免资源泄漏。例如,使用StreamReader读取文件时,可以这样处理:

using (StreamReader reader = new StreamReader("file.txt"))
{string content = reader.ReadToEnd();// 处理文件内容
} // 在此处自动调用 reader.Dispose() 释放资源

3. 异常处理的最佳实践

3.1 不要过度使用异常

异常处理应该用于处理真正的异常情况,而不是用于控制程序流程。过度使用异常会影响程序的性能和可维护性。

3.2 使用特定的异常类型

尽可能使用特定的异常类型来捕获和处理异常,这样可以更精确地处理不同类型的错误情况。

3.3 不要捕获所有异常

避免在一个大的catch块中捕获所有异常,这会导致不容易定位和解决问题。应根据不同的异常情况提供适当的处理。

3.4 使用 finally 进行资源释放

在使用可能会占用资源的对象(如文件、数据库连接等)时,应使用finally块确保资源在不管是否发生异常的情况下都能被释放。

3.5 记录异常信息

捕获到的异常应该至少记录错误信息,以便于调试和故障排除。可以使用日志记录库或输出到控制台。

3.6 自定义异常类

对于特定的业务逻辑或应用,可以创建自定义异常类来提供更有意义的异常信息,方便调试和处理。

3.7 嵌套异常处理

在一些情况下,可以在内部处理异常,然后在外部捕获并记录异常信息。

try
{try{// 可能引发异常的代码}catch (Exception ex){// 内部处理异常}
}
catch (Exception ex)
{Console.WriteLine("外部捕获异常:" + ex.Message);
}

3.8 全局异常处理

您还可以在应用程序级别设置全局异常处理,以处理未在特定地点捕获的异常。这可以通过订阅AppDomain.CurrentDomain.UnhandledException事件来实现。

class Program
{static void Main(string[] args){AppDomain.CurrentDomain.UnhandledException += GlobalExceptionHandler;try{// 可能引发异常的代码}catch (Exception ex){Console.WriteLine("发生异常:" + ex.Message);}}static void GlobalExceptionHandler(object sender, UnhandledExceptionEventArgs e){Exception ex = (Exception)e.ExceptionObject;Console.WriteLine("全局异常处理:" + ex.Message);// 可以在这里记录日志等操作}
}

4. 异常处理实例

以下是一个使用异常处理的示例,演示了如何读取文件内容并进行错误处理:

try
{using (StreamReader reader = new StreamReader("file.txt")){string content = reader.ReadToEnd();Console.WriteLine("文件内容:" + content);}
}
catch (FileNotFoundException ex)
{Console.WriteLine("文件不存在:" + ex.Message);
}
catch (IOException ex)
{Console.WriteLine("IO错误:" + ex.Message);
}
catch (Exception ex)
{Console.WriteLine("发生异常:" + ex.Message);
}
finally
{Console.WriteLine("处理结束。");
}

在上述示例中,我们使用了try-catch块来捕获不同类型的异常,处理了文件不存在和IO错误的情况,同时还使用了finally块进行清理操作。

5. 总结

异常处理是编程中的重要部分,用于捕获和处理程序运行时可能发生的错误情况,以确保程序的稳定性和健壮性。在C#中,您可以使用try-catch块、finally块和throw关键字来实现异常处理。通过选择恰当的异常类型、适当的异常处理策略以及遵循最佳实践,您可以提高程序的可靠性和可维护性。同时,了解何时使用自定义异常、全局异常处理和资源释放等技术也是编写高质量代码的重要一环。

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

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

相关文章

【碎碎念随笔】1、回顾我的电脑和编程经历

✏️ 闲着无事,讲述一下我的计算机和代码故事 一、初识计算机 🖥️ 余家贫,耕植无钱买电脑。大约六年级暑假,我在姐姐哪儿第一次接触到了计算机(姐姐也是买的二手)。 🖥️ 计算机真有趣&#x…

多线程并发服务器

代码&#xff1a; #include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h> #include <unistd.h> #define PORT 6666 //1024~49151 #define IP "192.168.122.130" //ifconfig查看本机IP #include <pthread.h> //…

探索Python编程的技巧:多线程魔法、网络舞台、正则魔法阵与递归迷宫

一 多线程 1.1 进程和线程 进程&#xff1a; 就是一个程序&#xff0c;运行在系统之上&#xff0c;称这个程序为一个运行进程&#xff0c;并分配进程ID方便系统管理。线程&#xff1a;线程是归属于进程的&#xff0c;一个进程可以开启多个线程&#xff0c;执行不同的工作&…

【C++面向对象】--- 继承 的奥秘(下篇)

个人主页&#xff1a;平行线也会相交&#x1f4aa; 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 平行线也会相交 原创 收录于专栏【C之路】&#x1f48c; 本专栏旨在记录C的学习路线&#xff0c;望对大家有所帮助&#x1f647;‍ 希望我们一起努力、成长&…

Postman接口自动化测试实战,从0到1一篇彻底打通...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 postman中的测试 …

【网络基础】传输层

【网络基础】传输层 文章目录 【网络基础】传输层1、端口号1.1 工具 2、UDP协议2.1 协议端格式2.2 UDP特点2.3 传输数据报2.4 缓冲区2.5 基于UDP应用层协议2.6 使用注意事项 3、TCP协议3.1 协议段格式3.2 ACK机制3.3 超时重传机制3.4 连接管理机制3.5 滑动窗口3.6 流量控制3.7 …

207、仿真-51单片机脉搏心率与血氧报警Proteus仿真设计(程序+Proteus仿真+配套资料等)

毕设帮助、开题指导、技术解答(有偿)见文未 目录 一、硬件设计 二、设计功能 三、Proteus仿真图 四、程序源码 资料包括&#xff1a; 需要完整的资料可以点击下面的名片加下我&#xff0c;找我要资源压缩包的百度网盘下载地址及提取码。 方案选择 单片机的选择 方案一&a…

猿辅导Motiff与IXDC达成战略合作,将在UI设计领域推动AI革新更多可能性

近日&#xff0c;“IXDC 2023国际体验设计大会”在北京国家会议中心拉开序幕&#xff0c;3000设计师、1000企业、200全球商业领袖&#xff0c;共襄为期5天的用户体验创新盛会。据了解&#xff0c;此次大会是以“设计领导力”为主题&#xff0c;分享全球设计、科技、商业的前沿趋…

报错解决:matlab机器人工具箱不支持将脚本 DHFactor 作为函数执行

matlab使用机器人工具箱出现报错&#xff1a; 不支持将脚本 DHFactor 作为函数执行: D:\MATLAB\install\toolbox\rvctools\robot\DHFactor.m 解决办法&#xff1a;重新到上图的rvctool重重新安装一下工具箱就好了。 到目录"$机器人工具箱路径$\rvctools" 在matlab命…

使用Scanner接收用户输入

扫描输入的两种方式 Scanner主要提供了两个方法来扫描输入&#xff1a; &#xff08;1&#xff09;hasNextXxx()&#xff1a;是否还有下一个输入项&#xff0c;Xxx可以是Int&#xff0c;Long等代表基本数据类型的字符串。 如果只是判断是否包含下一个字符串&#xff0c;则直…

新手开抖店多久可以出单?

​开抖店是一种越来越流行的创业方式&#xff0c;在社交媒体平台上开店销售各种商品&#xff0c;比如服装、配饰、美妆和家居用品等等。对于新手来说&#xff0c;他们可能会很关心自己开抖店能够多久出单。虽然这个问题没有一个固定的答案&#xff0c;但是以下是一些关键的运营…

【boost网络库从青铜到王者】第三篇:asio网络编程中的buffer缓存数据结构

文章目录 1、关于buffer数据结构1.1、简单概括一下&#xff0c;我们可以用buffer() 函数生成我们要用的缓存存储数据。1.2、但是这太复杂了&#xff0c;可以直接用buffer函数转化为send需要的参数类型:1.3、output_buf可以直接传递给该send接口。我们也可以将数组转化为send接受…

docker发展历史

docker 一、docker发展历史很久以前2013年2014年2015年2016年2017年2018年2019年及未来 二、 docker概述定义&#xff1a;docker底层运行原理:docker简述核心概念容器特点Docker与虚拟机的区别: 三、容器在内核中支持两种重要技术四、namespace的六项隔离五、虚拟化产品有哪些1…

CAS 的执行流程 ?CAS 中 ABA 问题如何解决 ?CAS 在 Java 中有哪些实现类 ?

目录 1. CAS 的执行流程 2. CAS 中的 ABA 问题 3. 如何解决 CAS 中的 ABA 问题 4.CAS 在Java 中的实现类有哪些 1. CAS 的执行流程 CAS 比较并替换的大致流程是这样的&#xff1a; 它有三个操作单位&#xff1a;V&#xff08;内存值&#xff09;&#xff0c;A&#xff08;…

3D沉浸式旅游网站开发案例复盘【Three.js】

Plongez dans Lyon网站终于上线了。 我们与 Danka 团队和 Nico Icecream 共同努力&#xff0c;打造了一个令我们特别自豪的流畅的沉浸式网站。 这个网站是专为 ONLYON Tourism 和会议而建&#xff0c;旨在展示里昂最具标志性的活动场所。观看简短的介绍视频后&#xff0c;用户…

Android 面试笔记整理-Binder机制

作者&#xff1a;浪人笔记 面试可能会问到的问题 从IPC的方式问到Binder的优势为什么zygote跟其他服务进程的通讯不使用BinderBinder线程池和Binder机制 等等这些问题都是基于你对Binder的理解还有对其他IPC通讯的理解 IPC方式有多少种 传统的IPC方式有Socket、共享内存、管道…

云计算虚拟仿真实训平台

一、云计算虚拟仿真系统概述 云计算虚拟仿真系统是一种基于云计算技术和虚拟化技术的系统&#xff0c;用于实现各种仿真和模拟任务。它可以提供强大的计算能力和资源管理&#xff0c;为用户提供灵活、高效、可扩展的仿真环境。 该系统通常由一组服务器、网络和存储设备组成&am…

uniapp开发小程序-有分类和列表时,进入页面默认选中第一个分类

一、效果&#xff1a; 如下图所示&#xff0c;进入该页面后&#xff0c;默认选中第一个分类&#xff0c;以及第一个分类下的列表数据。 二、代码实现&#xff1a; 关键代码&#xff1a; 进入页面时&#xff0c;默认调用分类的接口&#xff0c;在分类接口里做判断&#xff…