63、.NET 异常处理
在.NET框架中,异常处理是管理运行时错误的核心机制。以下是.NET异常处理的全面概述:
异常层次结构
.NET中的所有异常都继承自System.Exception基类,主要异常类别包括:
- 系统异常:由CLR抛出(如NullReferenceException)
- 应用程序异常:由应用程序代码抛出
- 自定义异常:开发者定义的特定业务异常
异常处理关键字
try
{// 可能抛出异常的代码
}
catch (SpecificException ex) when (condition) // C# 6.0+ 异常过滤器
{// 处理特定异常
}
catch (Exception ex)
{// 处理所有其他异常
}
finally
{// 清理代码,无论是否发生异常都会执行
}
常见系统异常
异常信息 | 描述 |
---|---|
System.NullReferenceException | 尝试访问null对象的成员 |
System.IndexOutOfRangeException | 数组或集合访问越界 |
System.ArgumentException | 方法接收到无效参数 |
System.InvalidOperationException | 对象状态不适合调用方法 |
System.IO.IOException | 输入/输出操作失败 |
System.TimeoutException | 操作超时 |
System.NotSupportedException | 调用了不支持的方法 |
抛出异常
// 抛出新异常
throw new InvalidOperationException("操作无效");// 重新抛出当前异常(保留原始堆栈跟踪)
throw;// 包装异常(保留原始异常作为内部异常)
throw new CustomException("高级错误消息", innerException);
创建自定义异常
[Serializable] // 支持序列化
public class CustomBusinessException : Exception
{public CustomBusinessException() : base("默认业务异常消息") { }public CustomBusinessException(string message) : base(message) { }public CustomBusinessException(string message, Exception innerException) : base(message, innerException) { }// 可选:实现序列化构造函数protected CustomBusinessException(SerializationInfo info, StreamingContext context): base(info, context) { }
}
异常处理最佳实践
- 具体优先:先捕获具体异常,再捕获一般异常
- 避免空catch块:至少记录异常信息
- 资源清理:使用finally或using语句
- 不要滥用异常:异常应用于异常情况,而非控制流程
- 提供上下文信息:在自定义异常中包含有用的业务上下文
- 考虑性能:异常处理比正常流程开销大
高级异常处理技术
1. 异常策略(Enterprise Library等)
// 使用策略处理异常(示例)
ExceptionPolicy.HandleException(exception, "Business Policy");
2. 异常屏蔽(ASP.NET Core)
// 在中间件中处理全局异常
app.UseExceptionHandler("/error");
3. 异步异常处理
try
{await SomeAsyncMethod();
}
catch (TaskCanceledException ex)
{// 处理取消操作
}
日志记录集成
try
{// 业务代码
}
catch (Exception ex)
{logger.LogError(ex, "发生业务异常");throw new CustomBusinessException("处理失败", ex);
}
异常处理与依赖注入
在ASP.NET Core等框架中,可以利用DI进行异常处理:
// 注册异常处理服务
services.AddScoped<IExceptionHandler, CustomExceptionHandler>();// 在控制器中使用
public class MyController : Controller
{private readonly IExceptionHandler _exceptionHandler;public MyController(IExceptionHandler exceptionHandler){_exceptionHandler = exceptionHandler;}public IActionResult DoSomething(){try { /* ... */ }catch (Exception ex) { return _exceptionHandler.Handle(ex); }}
}
跨平台考虑
在.NET Core/.NET 5+中,异常处理与平台无关,但需要注意:
- 某些平台特定异常可能在不同OS上有不同行为
- 文件路径异常在不同文件系统上表现可能不同
- 序列化异常时要考虑跨平台兼容性
正确理解和应用异常处理是构建健壮、可维护.NET应用程序的关键部分。