当前位置: 首页 > news >正文

C#异常捕获try catch详细介绍

在C#中,异常处理是通过trycatchfinallythrow语句来实现的,它们提供了一种结构化和可预测的方法来处理运行时错误。

C#异常基本用法

try块

异常处理以try块开始,try块包含可能会引发异常的代码。如果在try块中的代码执行过程中发生了异常,控制流将转移到与之匹配的catch块。

try
{// 可能会抛出异常的代码
}

catch块

catch块紧随try块之后,用于捕获和处理异常。可以有多个catch块来捕获不同类型的异常,每个catch块只处理特定类型的异常。

catch (SpecificExceptionType ex)
{// 处理特定类型的异常
}
catch (AnotherExceptionType ex)
{// 处理另一种类型的异常
}
catch
{// 捕获所有未被前面的catch块处理的异常
}

每个catch块可以指定一个异常变量来接收异常的详细信息,如消息、堆栈跟踪等。

finally块

finally块是可选的,它无论是否发生异常都会执行。finally块通常用于清理资源,比如关闭文件流、数据库连接等。

finally
{// 清理代码,无论是否发生异常都会执行
}

throw语句

throw语句用于触发异常。你可以重新抛出当前捕获的异常,或者抛出一个新的异常。

throw; // 重新抛出当前异常throw new Exception("New exception message"); // 抛出一个新的异常

自定义异常

你还可以定义自己的异常类,通过继承System.Exception类来实现。

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

然后,你可以像使用内置异常类型一样使用你的自定义异常类型。

完整的异常处理示例

下面是一个展示了如何使用trycatchfinallythrow的完整示例:

using System;class ExceptionHandlingExample
{static void Main(){try{Console.WriteLine("Enter a number to divide 100: ");int divisor = Convert.ToInt32(Console.ReadLine());int result = 100 / divisor;Console.WriteLine("Result is: " + result);}catch (DivideByZeroException ex){Console.WriteLine("Cannot divide by zero. Please try again.");}catch (FormatException ex){Console.WriteLine("That's not a valid number. Please try again.");}catch (Exception ex){Console.WriteLine($"An unexpected error occurred: {ex.Message}");throw; // 可以选择重新抛出异常}finally{// 这里的代码不管是否发生异常都会执行Console.WriteLine("Thanks for using our program.");}}
}

在这个例子中,程序尝试将100除以用户输入的数。如果用户输入了非数字或是0,程序将捕获并处理FormatExceptionDivideByZeroException。无论是否发生异常,finally块都会执行,程序以友好的消息结束。在通用catch块中,异常被重新抛出,这允许异常向上传递,可能被更高级别的异常处理器处理。

异常处理是C#中处理错误的关键部分,能够帮助你创建健壮和易于维护的应用程序。正确使用异常处理能够让你的代码在面对错误时更加优雅地失败,并且提供了足够的信息来帮助调试问题。

自定义异常

在C#中,你可以创建自定义异常以表示应用程序特定的错误情况。自定义异常通常用于提供比标准异常更详细的错误信息或者处理特定于应用程序的错误情况。

要创建自定义异常,你需要从System.Exception类继承,并建议遵循以下步骤:

  1. 命名自定义异常:异常名称通常以“Exception”结尾。
  2. 构造函数:提供几个构造函数,至少要提供与基类Exception相同的四个基本构造函数。
  3. 序列化支持:如果你的异常类需要在不同的应用程序域之间传递(例如,在远程方法调用中),它必须是可序列化的。(需要标记[Serializable]属性,并实现序列化接口)

以下是创建自定义异常的示例:

using System;
using System.Runtime.Serialization;[Serializable] // 可序列化
public class MyCustomException : Exception
{// 默认构造函数public MyCustomException(){}// 带错误消息的构造函数public MyCustomException(string message): base(message){}// 带错误消息和内部异常的构造函数(用于异常链)public MyCustomException(string message, Exception innerException): base(message, innerException){}// 实现序列化功能的构造函数protected MyCustomException(SerializationInfo info, StreamingContext context): base(info, context){}// 你可以添加额外的属性和方法来支持你的自定义异常的特殊需求
}

要抛出这个自定义异常,你可以使用throw关键字,像这样:

throw new MyCustomException("This is a custom error message.");

如果你需要在异常中包含更多上下文信息,你可以往自定义异常中添加额外的属性和方法。例如,如果你正在处理与用户账户相关的错误,你的自定义异常可能需要包含一个用户ID或用户名属性。

使用自定义异常的好处是能够清晰地表达发生了什么类型的错误,并且可以携带更多的上下文信息。此外,它们使得错误处理代码更加清晰,因为异常类型直接表明了发生的错误,而不必依赖解析错误消息字符串。记住,你应该只在标准异常不足以表达特定错误情况时创建自定义异常。

throw和throw ex有什么区别

在C#中,throwthrow ex 用于抛出异常,但它们的行为有重要差异:

  1. throw

    • 使用 throw 关键字不带任何参数重新抛出当前处理的异常。
    • 它保留了原始异常的堆栈跟踪,因此你可以看到异常最初是从哪里抛出的。
    try
    {// 代码可能抛出异常
    }
    catch (Exception)
    {// 处理异常throw; // 重新抛出当前异常
    }
    
  2. throw ex

    • 使用 throw ex 重新抛出在 catch 块中捕获的异常变量 ex
    • 这种方式会重置异常的堆栈跟踪,堆栈跟踪将从当前位置开始,而不是最初抛出异常的位置。
    • 这通常被认为是一种不良的做法,因为它隐藏了引发异常的原始位置,使得调试更加困难。
    try
    {// 代码可能抛出异常
    }
    catch (Exception ex)
    {// 处理异常throw ex; // 重新抛出异常,但会丢失原始堆栈跟踪
    }
    

因此,在大多数情况下,如果你需要在 catch 块中重新抛出异常,应该使用 throw 而不是 throw ex 以保留完整的堆栈信息。保持异常的堆栈跟踪对于诊断问题是非常重要的,因为它显示了异常发生的完整调用序列。

然而,如果你的目的是创建并抛出一个全新的异常(可能会附加一些额外的信息),而不是重新抛出原始异常,那么你会创建一个新的异常实例并使用 throw 关键字抛出它:

try
{// 代码可能抛出异常
}
catch (Exception ex)
{// 创建一个新的异常实例,可能会包含更多信息或者是自定义异常throw new MyCustomException("Additional message", ex);
}

在这种情况下,MyCustomException 将包含一个内部异常 ex,这样你就可以在处理自定义异常的同时,仍然访问到最初异常的信息。

finally和finalize block的区别

在C#中,“finally”块和“finalize”方法是两个不同的概念,它们用于不同的目的。

finally块

finally块是与trycatch块一起使用的,用于确保无论是否发生异常,都会执行一段代码。finally块常用于资源清理工作,比如关闭文件流、数据库连接等。

这里是一个finally块的示例:

using System;
using System.IO;class FinallyExample
{static void Main(){FileStream file = null;try{file = File.Open("example.txt", FileMode.Open);// 执行一些操作}catch (Exception ex){Console.WriteLine(ex.Message);}finally{// 无论是否发生异常,都会执行finally块中的代码if (file != null){file.Close();Console.WriteLine("File stream closed.");}}}
}

在上面的代码中,无论try块中的代码是否成功,或者是否触发了catch块,finally块都会被执行。

finalize方法

finalize方法是一个在对象即将被垃圾回收前执行的清理方法。在C#中,它通过重写Object类的Finalize方法来实现。注意,在.NET中,通常不推荐显式重写Finalize方法,而是建议使用IDisposable接口和Dispose方法来处理资源清理。

这里是一个finalize方法的示例:

using System;class FinalizeExample
{// 析构函数~FinalizeExample(){// 这里是在对象即将被销毁时会执行的代码Console.WriteLine("Finalize method called.");}
}class Program
{static void Main(){FinalizeExample example = new FinalizeExample();// 当example不再被使用时,垃圾回收器在回收之前会调用其Finalize方法example = null;GC.Collect(); // 强制垃圾回收(仅用于示例,通常不建议这么做)GC.WaitForPendingFinalizers(); // 等待所有的Finalizer方法执行完毕}
}

在这个示例中,FinalizeExample类有一个析构函数(在C#中以~开头),这个析构函数就是Finalize方法的语法糖。当垃圾回收器决定回收这个对象的内存时,会自动调用这个析构函数。

总结

  • finally块是用于异常处理的,确保代码的执行,通常用于释放资源。
  • finalize方法(析构函数)是在对象被垃圾回收前自动调用的,用于执行对象的清理代码。

在实际开发中,finalize方法的使用应该非常谨慎,因为垃圾回收器调用Finalize方法的时间是不确定的。相比之下,IDisposable接口和using语句是更可控、更常见的资源管理机制。

相关文章:

C#异常捕获try catch详细介绍

在C#中,异常处理是通过try、catch、finally和throw语句来实现的,它们提供了一种结构化和可预测的方法来处理运行时错误。 C#异常基本用法 try块 异常处理以try块开始,try块包含可能会引发异常的代码。如果在try块中的代码执行过程中发生了…...

切换阿里云ES方式及故障应急处理方案

一、阿里云es服务相关问题及答解 1.1 ES7.10扩容节点时间 增加节点数量需要节点拉起和数据Rebalance两步,拉起时间7.16及以上的新版本大概10分钟以内,7.16以前大概一小时,数据迁移的时间就看数据量了,一般整体在半小时以内 (需进行相关测试验证) 1.2 ES7.10扩容数据节点…...

CTFhub-RCE-过滤空格

1. 查看当前目录&#xff1a;127.0.0.1|ls 2. 查看 flag_890277429145.php 127.0.0.1|cat flag_890277429145.php 根据题目可以知道空格被过滤掉了 3.空格可以用以下字符代替&#xff1a; < 、>、<>、%20(space)、%09(tab)、$IFS$9、 ${IFS}、$IFS等 $IFS在li…...

无需添加udid,ios企业证书的自助生成方法

我们开发uniapp的app的时候&#xff0c;需要苹果证书去打包。 假如申请的是个人或company类型的苹果开发者账号&#xff0c;必须上架才能安装&#xff0c;异常的麻烦&#xff0c;但是有一些app&#xff0c;比如企业内部使用的app&#xff0c;是不需要上架苹果应用市场的。 假…...

【PTA题目】6-20 使用函数判断完全平方数 分数 10

6-20 使用函数判断完全平方数 分数 10 全屏浏览题目 切换布局 作者 张高燕 单位 浙大城市学院 本题要求实现一个判断整数是否为完全平方数的简单函数。 函数接口定义&#xff1a; int IsSquare( int n ); 其中n是用户传入的参数&#xff0c;在长整型范围内。如果n是完全…...

Nas搭建webdav服务器并同步Zotero科研文献

无需云盘&#xff0c;不限流量实现Zotero跨平台同步&#xff1a;内网穿透私有WebDAV服务器 文章目录 无需云盘&#xff0c;不限流量实现Zotero跨平台同步&#xff1a;内网穿透私有WebDAV服务器一、Zotero安装教程二、群晖NAS WebDAV设置三、Zotero设置四、使用公网地址同步Zote…...

一句话总结敏捷实践中不同方法

敏捷实践是指一组优先考虑灵活性、协作和客户满意度的软件开发和项目管理原则和方法。 不同方法论的敏捷实践&#xff1a; 1、敏捷&#xff1a; Sprints&#xff1a;限时迭代&#xff08;通常 2-4 周&#xff09;&#xff0c;在此期间创建潜在的可交付产品增量。每日站立会议…...

【数据结构】线段树(点修区查)

数据结构-线段树&#xff08;点修区查&#xff09; 前置知识 分治递归二叉树 思路 我们需要维护一个支持单点修改&#xff0c;区间查询的数据结构&#xff0c;并且要求在线&#xff0c;一般使用线段树解决。 线段树是一个二叉树形的数据结构。 线段树的思想很简单&#xff0c…...

Ansys Lumerical | 用于增强现实系统的表面浮雕光栅

在本示例中&#xff0c;我们使用 RCWA 求解器设计了一个斜面浮雕光栅 (SRG)&#xff0c;它将用于将光线耦合到单色增强现实 (AR) 系统的波导中。光栅的几何形状经过优化&#xff0c;可将正常入射光导入-1 光栅阶次。 然后我们将光栅特性导出为 Lumerical Sub-Wavelength Model …...

QT day3作业

1.思维导图 2、 完善对话框&#xff0c;点击登录对话框&#xff0c;如果账号和密码匹配&#xff0c;则弹出信息对话框&#xff0c;给出提示”登录成功“&#xff0c;提供一个Ok按钮&#xff0c;用户点击Ok后&#xff0c;关闭登录界面&#xff0c;跳转到其他界面 如果账号和密…...

【Ubuntu】设置永不息屏与安装 dconf-editor

方式一、GUI界面进行设置 No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 20.04.6 LTS Release: 20.04 Codename: focal打开 Ubuntu 桌面环境的设置菜单。你可以通过点击屏幕右上角的系统菜单&#xff0c;然后选择设置。在设置菜单中&#xff0c;…...

gRPC 的原理 介绍带你从头了解gRPC

gRPC 的原理 什么是gRPC gRPC的官方介绍是&#xff1a;gRPC是一个现代的、高性能、开源的和语言无关的通用 RPC 框架&#xff0c;基于 HTTP2 协议设计&#xff0c;序列化使用PB(Protocol Buffer)&#xff0c;PB 是一种语言无关的高性能序列化框架&#xff0c;基于 HTTP2PB 保…...

Apriori算法

Apriori算法由R. Agrawal和R. Srikant于1994年在数据集中寻找布尔关联规则的频繁项集。该算法的名称是Apriori&#xff0c;因为它使用了频繁项集属性的先验知识。我们应用迭代方法或逐层搜索&#xff0c;其中k-频繁项集用于找到k1个项集。 为了提高频繁项集逐层生成的效率&…...

肖sir__linux讲解(2.1)

linux命令 cp 复制命令 a、cp 原文件名称 新文 件名称&#xff08;不存在的文件&#xff09; 案例&#xff1a;cp a k 截图&#xff1a; b.cp 原文件名称 原有文 件名称&#xff08;存在的文件&#xff09; 案例:cp a b 截图&#xff1a; c、cp 指定路径复制 格式&#xff…...

The ultimate UI kit and design system for Figma 组件库下载

Untitled UI 是世界上最大的 Figma UI 套件和设计系统。可以启动任何项目&#xff0c;为您节省数千小时&#xff0c;并祝您升级为专业设计师。 采用 100% 自动布局 5.0、变量、智能变体和 WCAG 可访问性精心制作。 900全局样式、变量&#xff1a;超级智能的全局颜色、排版和效…...

Selenium——利用input标签上传文件

Selenium利用input标签上传文件 完整流程 打开文件上传页面选择要上传的文件点击上传按钮确认文件上传成功介绍怎么方便的获取对应元素的Xpath或者Css 简单介绍 在使用Selenium进行浏览器自动化测试时&#xff0c;文件上传是一个常见的需求。而 标签就是实现文件上传功能的…...

C++初阶 日期类的实现(下)

目录 一、输入输出(>>,<<)重载的实现 1.1初始版 1.2友元并修改 1.2.1简单介绍下友元 1.2.2修改 1.3>>重载 二、条件判断操作符的实现 2.1操作符的实现 2.2!操作符的实现 2.3>操作符的实现 2.4>,<,<操作符的实现 三、日期-日期的实现 …...

大师学SwiftUI第16章 - UIKit框架集成

其它相关内容请见​​虚拟现实(VR)/增强现实(AR)&visionOS开发学习笔记​​ SwiftUI是一套新框架&#xff0c;因此并没有包含我们构建专业应用所需的所有工具。这意味着我们会需要求助于UIKit&#xff08;移动设备&#xff09;和AppKit&#xff08;Mac电脑&#xff09;等原…...

7.docker运行redis容器

1.准备redis的配置文件 从上一篇运行MySQL容器我们知道&#xff0c;需要给容器挂载数据卷&#xff0c;来持久化数据和配置&#xff0c;相应的redis也不例外。这里我们以redis6.0.8为例来实际说明下。 1.1 查找redis的配置文件redis.conf 下面这个网址有各种版本的配置文件供…...

unity教程

前言 伴随游戏行业的兴起&#xff0c;unity引擎的使用越来越普遍&#xff0c;本文章主要记录博主本人入门unity的相关记录大部分依赖siki学院进行整理。12 一、认识unity引擎&#xff1f; 1、Unity相关信息&#xff1a; Unity的诞生&#xff1a;https://www.jianshu.com/p/550…...

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...

java_网络服务相关_gateway_nacos_feign区别联系

1. spring-cloud-starter-gateway 作用&#xff1a;作为微服务架构的网关&#xff0c;统一入口&#xff0c;处理所有外部请求。 核心能力&#xff1a; 路由转发&#xff08;基于路径、服务名等&#xff09;过滤器&#xff08;鉴权、限流、日志、Header 处理&#xff09;支持负…...

利用ngx_stream_return_module构建简易 TCP/UDP 响应网关

一、模块概述 ngx_stream_return_module 提供了一个极简的指令&#xff1a; return <value>;在收到客户端连接后&#xff0c;立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量&#xff08;如 $time_iso8601、$remote_addr 等&#xff09;&a…...

Spring Boot 实现流式响应(兼容 2.7.x)

在实际开发中&#xff0c;我们可能会遇到一些流式数据处理的场景&#xff0c;比如接收来自上游接口的 Server-Sent Events&#xff08;SSE&#xff09; 或 流式 JSON 内容&#xff0c;并将其原样中转给前端页面或客户端。这种情况下&#xff0c;传统的 RestTemplate 缓存机制会…...

线程与协程

1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指&#xff1a;像函数调用/返回一样轻量地完成任务切换。 举例说明&#xff1a; 当你在程序中写一个函数调用&#xff1a; funcA() 然后 funcA 执行完后返回&…...

HTML 列表、表格、表单

1 列表标签 作用&#xff1a;布局内容排列整齐的区域 列表分类&#xff1a;无序列表、有序列表、定义列表。 例如&#xff1a; 1.1 无序列表 标签&#xff1a;ul 嵌套 li&#xff0c;ul是无序列表&#xff0c;li是列表条目。 注意事项&#xff1a; ul 标签里面只能包裹 li…...

【机器视觉】单目测距——运动结构恢复

ps&#xff1a;图是随便找的&#xff0c;为了凑个封面 前言 在前面对光流法进行进一步改进&#xff0c;希望将2D光流推广至3D场景流时&#xff0c;发现2D转3D过程中存在尺度歧义问题&#xff0c;需要补全摄像头拍摄图像中缺失的深度信息&#xff0c;否则解空间不收敛&#xf…...

TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案

一、TRS收益互换的本质与业务逻辑 &#xff08;一&#xff09;概念解析 TRS&#xff08;Total Return Swap&#xff09;收益互换是一种金融衍生工具&#xff0c;指交易双方约定在未来一定期限内&#xff0c;基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...

【AI学习】三、AI算法中的向量

在人工智能&#xff08;AI&#xff09;算法中&#xff0c;向量&#xff08;Vector&#xff09;是一种将现实世界中的数据&#xff08;如图像、文本、音频等&#xff09;转化为计算机可处理的数值型特征表示的工具。它是连接人类认知&#xff08;如语义、视觉特征&#xff09;与…...

MySQL 8.0 OCP 英文题库解析(十三)

Oracle 为庆祝 MySQL 30 周年&#xff0c;截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始&#xff0c;将英文题库免费公布出来&#xff0c;并进行解析&#xff0c;帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...