跳到主要内容

C# 异常过滤器

介绍

在 C# 中,异常处理是确保程序健壮性和稳定性的重要部分。传统的 try-catch 语句允许我们捕获并处理异常,但有时我们希望在捕获异常之前对其进行一些条件检查。这就是 异常过滤器 的用武之地。

异常过滤器是 C# 6.0 引入的一项功能,它允许我们在 catch 块中指定一个条件表达式。只有当该条件为 true 时,异常才会被捕获和处理。这使得异常处理更加灵活和精确。

异常过滤器的语法

异常过滤器的语法非常简单。在 catch 块中,使用 when 关键字后跟一个布尔表达式即可:

csharp
try
{
// 可能抛出异常的代码
}
catch (Exception ex) when (ex.Message.Contains("特定条件"))
{
// 只有当异常消息包含 "特定条件" 时才会执行
}

示例 1:基本用法

以下是一个简单的示例,展示了如何使用异常过滤器:

csharp
try
{
throw new Exception("这是一个测试异常");
}
catch (Exception ex) when (ex.Message.Contains("测试"))
{
Console.WriteLine("捕获到包含 '测试' 的异常");
}
catch (Exception ex)
{
Console.WriteLine("捕获到其他异常");
}

输出:

捕获到包含 '测试' 的异常

在这个示例中,只有当异常消息包含 "测试" 时,第一个 catch 块才会执行。否则,异常将被第二个 catch 块捕获。

异常过滤器的优势

  1. 更精确的异常处理:通过条件过滤,可以更精确地捕获和处理特定类型的异常。
  2. 避免重复代码:不需要在 catch 块内部编写条件语句,代码更加简洁。
  3. 调试友好:异常过滤器不会影响堆栈跟踪,调试时更容易定位问题。

实际应用场景

场景 1:处理特定类型的异常

假设我们正在开发一个文件处理应用程序,需要处理不同类型的文件读取异常。我们可以使用异常过滤器来区分不同的异常情况:

csharp
try
{
// 尝试读取文件
}
catch (IOException ex) when (ex.Message.Contains("文件未找到"))
{
Console.WriteLine("文件未找到,请检查路径");
}
catch (IOException ex) when (ex.Message.Contains("访问被拒绝"))
{
Console.WriteLine("没有权限访问该文件");
}
catch (IOException ex)
{
Console.WriteLine("其他 IO 异常");
}

场景 2:日志记录

在日志记录中,我们可能只想记录特定条件的异常。例如,只记录严重程度较高的异常:

csharp
try
{
// 业务逻辑
}
catch (Exception ex) when (LogException(ex))
{
// 只有当 LogException 返回 true 时才会执行
}

bool LogException(Exception ex)
{
if (ex is NullReferenceException)
{
Console.WriteLine("记录 NullReferenceException");
return true;
}
return false;
}

总结

C# 异常过滤器为异常处理提供了更高的灵活性和精确性。通过 when 关键字,我们可以在捕获异常之前进行条件检查,从而编写更简洁、更高效的代码。在实际开发中,异常过滤器可以帮助我们更好地处理特定场景下的异常,提升程序的健壮性。

附加资源

练习

  1. 编写一个程序,使用异常过滤器捕获并处理 DivideByZeroException,但只在除数为 0 时捕获。
  2. 修改上述文件处理示例,添加一个新的异常过滤器,处理文件大小超过限制的情况。
提示

在编写异常过滤器时,确保条件表达式不会抛出异常,否则可能会导致未处理的异常。