C# 异常处理(Exception Handling)
本章节全面详细的了解 C# 异常处理(Exception Handling),内容涵盖:
- 基础概念与结构
- 常见内置异常类型
- 自定义异常类
- 多层嵌套与异常传播机制
- 异常过滤器(C# 6+)
- 异常处理最佳实践
- 实战案例
- 实用参考链接
一、C# 异常处理基础结构
C# 使用 try-catch-finally 来处理异常,语法如下:
try
{
// 尝试执行的代码(可能会抛出异常)
}
catch (Exception ex)
{
// 处理异常
}
finally
{
// 无论是否抛出异常,都会执行
}
二、常见的内置异常类型
| 异常类型 | 描述 |
|---|---|
System.Exception | 所有异常的基类 |
NullReferenceException | 对象未实例化 |
ArgumentException | 参数无效 |
ArgumentNullException | 参数为 null |
IndexOutOfRangeException | 索引超出范围 |
DivideByZeroException | 除数为零 |
FileNotFoundException | 文件未找到 |
InvalidOperationException | 操作不合法 |
三、自定义异常类(继承 Exception)
public class MyCustomException : Exception
{
public MyCustomException(string message) : base(message) { }
public override string ToString()
{
return $"[自定义异常] {Message}";
}
}
使用:
throw new MyCustomException("出现业务逻辑异常");
四、嵌套异常与异常传播
try
{
DoSomething();
}
catch (Exception ex)
{
throw new Exception("包装错误", ex); // 异常链
}
可以通过 ex.InnerException 获取原始错误。
五、异常过滤器(C# 6.0+)
条件捕获异常的方式:
try
{
throw new InvalidOperationException("错误!");
}
catch (Exception ex) when (ex.Message.Contains("错误"))
{
Console.WriteLine("捕获包含‘错误’的异常");
}
六、异常处理最佳实践
| 建议 | 说明 |
|---|---|
| ❌ 不要用异常做流程控制 | 用 if-else 判断代替异常 |
| ✅ 尽量具体化捕获类型 | 如捕获 FileNotFoundException 而非所有异常 |
✅ 使用 using/try-finally 释放资源 | 保证资源释放 |
| ✅ 日志记录异常信息 | 如记录 ex.Message 和 ex.StackTrace |
| ✅ 保持异常原始栈信息 | 用 throw; 而非 throw ex; |
七、实战案例
✅ 示例 1:处理文件读写异常
try
{
string content = File.ReadAllText("data.txt");
Console.WriteLine(content);
}
catch (FileNotFoundException)
{
Console.WriteLine("❌ 文件未找到!");
}
catch (IOException ex)
{
Console.WriteLine($"IO 错误:{ex.Message}");
}
finally
{
Console.WriteLine("✅ 文件读取流程结束");
}
✅ 示例 2:业务逻辑中抛出异常
public void Withdraw(decimal amount)
{
if (amount <= 0)
throw new ArgumentException("金额必须大于零");
if (amount > balance)
throw new InvalidOperationException("余额不足");
}
✅ 示例 3:统一异常处理(ASP.NET Core 中间件)
app.UseExceptionHandler(errorApp =>
{
errorApp.Run(async context =>
{
var exceptionHandlerPathFeature = context.Features.Get<IExceptionHandlerPathFeature>();
var exception = exceptionHandlerPathFeature?.Error;
context.Response.ContentType = "application/json";
await context.Response.WriteAsync(JsonSerializer.Serialize(new {
error = exception?.Message,
stack = exception?.StackTrace
}));
});
});
八、参考文档与链接
更多详细内容,请关注其他相关文章!