在 C# 中,异常过滤器(Exception Filters)的运作机制是怎样的?
考察说明
考查对 C# 异常过滤器机制的理解,包括其执行时机、语法和与 catch 块的差异。
回答思路
- 【回答框架 1】异常过滤器是 C# 6.0 引入的特性,允许在 catch 块之前添加一个布尔条件,只有条件为 true 时才会进入对应的 catch 块。其语法为 catch (ExceptionType ex) when (condition),其中 when 关键字后跟一个表达式。
- 【回答框架 2】过滤器在异常被抛出时立即评估,且评估发生在栈展开之前。这意味着如果过滤器返回 false,异常会继续向上传播,且不会执行该 catch 块内的代码,但其他 catch 块仍有机会处理该异常。
- 【回答框架 3】与在 catch 块内使用 if 语句相比,异常过滤器的主要区别在于执行时机和堆栈信息保留。过滤器在栈展开前运行,因此保留了原始异常抛出点的堆栈信息,而 catch 块内的 if 语句在栈展开后执行,堆栈信息可能丢失。
- 【回答框架 4】异常过滤器可以访问异常对象,并可用于根据异常的类型、消息或其他属性进行精细的条件判断,而无需在 catch 块内再次抛出异常或进行额外的类型检查。
- 【回答框架 5】在性能方面,异常过滤器可能比在 catch 块内处理更高效,因为避免了不必要的栈展开和重新抛出,但实际性能影响取决于具体场景。
- 【关键点 1】异常过滤器使用 when 关键字,在 catch 块之前评估布尔条件。
- 【关键点 2】过滤器在栈展开前执行,保留原始异常堆栈信息。
- 【关键点 3】过滤器返回 false 时,异常继续向上传播,不进入当前 catch 块。
- 【关键点 4】与 catch 内 if 相比,过滤器避免了栈展开后丢失堆栈信息的问题。
- 【关键点 5】条件表达式不应抛出异常,以免掩盖原始异常。
- 【易错点 1】避免在过滤器中编写带有副作用的代码,因为过滤器可能在异常传播过程中被多次评估。
- 【易错点 2】过滤器中的条件表达式若抛出异常,会覆盖原始异常,导致调试困难。
- 【易错点 3】不要误以为过滤器返回 false 就会终止异常传播,实际上它会继续寻找其他匹配的 catch 块。