C# 异常处理(Exception Handling)
                           
天天向上
发布: 2025-04-13 14:50:04

原创
390 人浏览过

本章节全面详细的了解 C# 异常处理(Exception Handling),内容涵盖:

  1. 基础概念与结构
  2. 常见内置异常类型
  3. 自定义异常类
  4. 多层嵌套与异常传播机制
  5. 异常过滤器(C# 6+)
  6. 异常处理最佳实践
  7. 实战案例
  8. 实用参考链接

一、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.Messageex.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
        }));
    });
});

八、参考文档与链接


更多详细内容,请关注其他相关文章!

发表回复 0

Your email address will not be published. Required fields are marked *