C# 异常和异常处理的用法
概述
异常和异常处理的定义
异常:异常是在程序运行时发生的错误或不正常情况,会中断正常的执行流程。在C#中,异常通常是一个System.Exception类或其派生类的实例。
异常处理:异常处理是处理程序运行时出现的错误或不正常情况的机制。在C#中,主要涉及以下关键字和语句:
- try:用于包围可能会引发异常的代码块。
- catch:用于捕获并处理try块中引发的异常。
- finally:用于定义无论是否发生异常都会执行的代码块。
- throw:用于显式地引发一个异常。
异常的来源
异常可由 .NET Framework 公共语言运行时 (CLR) 或由程序中的代码引发。
- 由公共语言运行时(CLR)引发:
异常 |
说明 |
ArithmeticException |
算术运算中发生错误 |
ArrayTypeMismatchException |
数组类型不匹配 |
DivideByZeroException |
除零异常 |
IndexOutOfRangeException |
数组或集合的索引超出范围 |
InvalidCastException |
尝试将对象转换为不兼容的类型 |
NullReferenceException |
尝试访问一个未初始化的对象 |
OutOfMemoryException |
系统内存不足 |
OverflowException |
算术运算结果超出数据类型的范围 |
StackOverflowException |
堆栈溢出 |
TypeInitializationException |
静态构造函数中引发异常 |
异常 |
说明 |
ArgumentException |
方法参数无效 |
ArgumentNullException |
方法参数为 null |
ArgumentOutOfRangeException |
方法参数超出有效范围 |
InvalidOperationException |
在当前状态下不允许的操作 |
NotSupportedException |
不支持的操作或特性 |
ObjectDisposedException |
尝试使用已释放的对象 |
- 由程序代码引发:
异常 |
举例 |
显示抛出异常 |
throw new ArgumentException("参数值无效。"); |
方法调用引发异常 |
string content = File.ReadAllText(filePath); |
- 由外部资源或环境引发
异常 |
说明 |
FileNotFoundException |
文件未找到 |
DirectoryNotFoundException |
目录未找到 |
IOException |
输入/输出操作失败 |
UnauthorizedAccessException |
没有足够的权限访问文件或目录 |
异常 |
说明 |
SocketException |
网络套接字操作失败 |
WebException |
网络请求失败 |
HttpRequestException |
HTTP 请求失败 |
异常 |
说明 |
SqlException |
SQL Server 数据库操作失败 |
DbException |
数据库操作失败 |
异常 |
说明 |
COMException |
与 COM 组件交互时发生错误 |
SEHException |
结构化异常处理(SEH)错误 |
示例
场景描述
假设我们有一个文件管理系统,它的功能包括:
- 从指定的源文件读取内容。
- 验证文件内容是否符合特定格式。
- 将内容写入到目标文件。
- 处理可能出现的各种异常,如文件不存在、文件访问权限问题、内容验证失败等。
定义自定义异常类
为了处理不同类型的错误,我们定义了几个自定义异常类:
- FileReadException:当文件读取失败时抛出的异常。
- FileWriteException:当文件写入失败时抛出的异常。
- ContentValidationException:当文件内容验证失败时抛出的异常。
FileReadException.cs
| using System; |
| using System.Runtime.Serialization; |
| |
| [Serializable] |
| public class FileReadException : Exception |
| { |
| public FileReadException() : base() { } |
| public FileReadException(string message) : base(message) { } |
| public FileReadException(string message, Exception inner) : base(message, inner) { } |
| protected FileReadException(SerializationInfo info, StreamingContext context) : base(info, context) { } |
| } |
FileWriteException.cs
| using System; |
| using System.Runtime.Serialization; |
| |
| [Serializable] |
| public class FileWriteException : Exception |
| { |
| public FileWriteException() : base() { } |
| public FileWriteException(string message) : base(message) { } |
| public FileWriteException(string message, Exception inner) : base(message, inner) { } |
| protected FileWriteException(SerializationInfo info, StreamingContext context) : base(info, context) { } |
| } |
ContentValidationException.cs
| using System; |
| using System.Runtime.Serialization; |
| |
| [Serializable] |
| public class ContentValidationException : Exception |
| { |
| public ContentValidationException() : base() { } |
| public ContentValidationException(string message) : base(message) { } |
| public ContentValidationException(string message, Exception inner) : base(message, inner) { } |
| protected ContentValidationException(SerializationInfo info, StreamingContext context) : base(info, context) { } |
| } |
文件读写与内容验证
- 文件读取
| private static string ReadFile(string filePath) |
| { |
| try |
| { |
| return File.ReadAllText(filePath); |
| } |
| catch (FileNotFoundException ex) |
| { |
| throw new FileReadException($"文件未找到: {filePath}", ex); |
| } |
| catch (IOException ex) |
| { |
| throw new FileReadException($"读取文件时发生错误: {filePath}", ex); |
| } |
| } |
- 文件写入
| private static void WriteFile(string filePath, string content) |
| { |
| try |
| { |
| File.WriteAllText(filePath, content); |
| } |
| catch (UnauthorizedAccessException ex) |
| { |
| throw new FileWriteException($"写入文件时权限不足: {filePath}", ex); |
| } |
| catch (IOException ex) |
| { |
| throw new FileWriteException($"写入文件时发生错误: {filePath}", ex); |
| } |
| } |
- 内容验证
| private static void ValidateContent(string content) |
| { |
| string[] lines = content.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); |
| if (lines.Length == 0 || !lines[0].StartsWith("#")) |
| { |
| throw new ContentValidationException("文件内容验证失败: 文件必须以注释行开头。"); |
| } |
| } |
主程序
| using System; |
| using System.IO; |
| using System.Runtime.Serialization; |
| |
| public class Program |
| { |
| public static void Main() |
| { |
| string sourceFilePath = @"C:\source.txt"; |
| string destinationFilePath = @"C:\destination.txt"; |
| |
| try |
| { |
| |
| string content = ReadFile(sourceFilePath); |
| |
| |
| ValidateContent(content); |
| |
| |
| WriteFile(destinationFilePath, content); |
| |
| Console.WriteLine("文件内容已成功复制。"); |
| } |
| catch (FileReadException ex) |
| { |
| Console.WriteLine($"文件读取失败: {ex.Message}"); |
| throw new ApplicationException("无法完成文件操作。", ex); |
| } |
| catch (ContentValidationException ex) |
| { |
| Console.WriteLine($"内容验证失败: {ex.Message}"); |
| throw new ApplicationException("无法完成文件操作。", ex); |
| } |
| catch (FileWriteException ex) |
| { |
| Console.WriteLine($"文件写入失败: {ex.Message}"); |
| throw new ApplicationException("无法完成文件操作。", ex); |
| } |
| catch (Exception ex) |
| { |
| Console.WriteLine($"发生了一个未预期的错误: {ex.Message}"); |
| throw new ApplicationException("发生了一个未预期的错误。", ex); |
| } |
| } |
| } |
引发文件读取失败异常
- 将主程序中,修改文件路径为不存在的路径
| string sourceFilePath = @"C:\nosourcefile.txt"; |
| string destinationFilePath = @"C:\nodestinationfile.txt"; |
- 运行程序,在ReadFile方法中:捕获 FileNotFoundException 并抛出自定义的 FileReadException,将原始异常作为 InnerException 传递
- 在主程序中,捕获 FileReadException 并输出错误信息
- 同时,将捕获的异常作为 InnerException 重新抛出,以便保留原始异常的上下文信息
引用
- MSDN C# 编程指南&参考手册 2015
https://wizardforcel.gitbooks.io/msdn-csharp/content/index.html
声明
内容准确性: 我会尽力确保所分享信息的准确性和可靠性,但由于个人知识有限,难免会有疏漏或错误。如果您在阅读过程中发现任何问题,请不吝赐教,我将及时更正。
AI: 文章内容参考了DeepSeek、智谱清言大语言模型生成的内容。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix