C# 异常和异常处理的用法
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、智谱清言大语言模型生成的内容。
posted on 2025-02-06 17:34 wubing7755 阅读(169) 评论(0) 收藏 举报
浙公网安备 33010602011771号