try-catch代码块是C#中用于异常处理的核心机制。异常是在程序执行过程中可能出现的错误,而try-catch代码块允许您在执行代码时捕获并处理这些异常。
一、基础结构
try
{
//可能抛出异常的代码
}
catch (ArgumentException ex)
{
//处理特定异常
}
catch (Exception ex)
{
//处理其他异常
}
finally
{
//无论是否存在异常最终都会执行,可选
}
二、关键字详解
1、try
- 包裹可能抛出异常的代码
- 必须存在,后接catch或finally,或者二者都有
2、catch
- 捕获异常
- 按顺序执行
catch (ArgumentException ex)
{
Console.WriteLine("参数异常:",ex.Message);
}
catch (Exception ex)
{
Console.WriteLine("其他异常:", ex.Message);
}
3、finally
- 无论是否发生异常,都会执行
- 常用来释放资源(关闭文件、数据库连接等)
- 无异常时执行顺序 try→finally
- 存在异常时执行顺序 try-catch-finally
三、关键特性
1、继承
- 派生自 System.Exception
- 常见内置异常:
- 空引用:NullReferenceException
- 文件未找到:FileNotFoundException
2、抛出异常
catch (Exception ex)
{
//使用 throw,而不是 throw ex,抛出原始异常
throw;
}
3、异常筛选器 when(C# 6.0+)
使用when关键字筛选异常
catch (IOException ex) when (ex.Message.Contains("正在使用"))
{
Console.WriteLine("文件被占用");
}
四、使用
1、适用场景
- 数据库访问
- 文件/网络 I/O 操作
2、避免滥用
- 不要过度使用异常
异常处理是用于处理真正的异常情况的,而不应该被用于控制程序流程。过多的异常处理会影响性能和代码可读性 - 不用使用空的catch块
捕获到的异常至少应该记录错误信息,以便于调试和故障排除。可以使用日志记录库或输出到控制台 - 不要捕获所有异常
避免在一个大的catch块中捕获所有异常,这会导致难以定位问题。根据异常类型提供适当的处理 - 使用特定的异常类型
尽量使用特定的异常类型捕获和处理异常,这样可以更准确地针对不同类型的错误提供不同的处理逻辑 - 自定义异常类
在需要时,可以创建自定义异常类,以提供更有意义的异常信息和处理方式。有助于调试和错误处理
五、常见错误
- 捕获顺序错误:将 catch (Exception) 放在具体异常之前
- 忽略异常:空的 catch 块导致静默失败
- 资源泄漏:忘记在 finally 中关闭文件/连接
六、示例
try
{
var txt = File.ReadAllLines("tangshi.txt");
}
catch (FileNotFoundException ex)
{
Console.WriteLine($"文件未找到: {ex.FileName}");
}
catch (IOException ex) when (ex.Message.Contains("正在使用"))
{
Console.WriteLine("文件被占用");
}
catch (Exception ex)
{
Console.WriteLine($"未知错误: {ex.Message}");
}
finally
{
Console.WriteLine("清理完成");
}