C#面试题更新 2026-08-05

请解释在 C# 的异常处理中,使用 throw 语句与使用 throw ex 语句在行为上有哪些不同?

技术原理问题排查C#

考察说明

考查对异常堆栈跟踪保留机制的理解,以及正确实践以避免丢失原始异常信息。

回答思路

  1. 【回答框架 1】throw 语句用于重新抛出当前异常,它会保留原始的堆栈跟踪信息,因为 CLR 不会重置异常对象中的堆栈跟踪。而 throw ex 语句将当前异常对象作为新异常抛出,但会重置堆栈跟踪的起点为当前代码行,导致原始异常抛出位置丢失。
  2. 【回答框架 2】在 catch 块中,推荐使用 throw 而不是 throw ex,以便保留完整的异常调用链,便于调试。throw ex 通常被认为是不良实践,因为它会掩盖错误的根源。
  3. 【回答框架 3】如果需要向异常添加额外信息,可以创建新的异常实例并将原异常作为内部异常传入,或者使用 ExceptionDispatchInfo.Capture 和 Throw 方法来保留原始堆栈。
  4. 【回答框架 4】另外,在重抛异常时,堆栈跟踪显示的是原始抛出点,而非 catch 块所在位置,这有助于定位问题;而 throw ex 则几乎总是显示 catch 块内的行号,误导调试。
  5. 【回答框架 5】在性能方面,throw 与 throw ex 的差异极小,主要在于堆栈跟踪的完整性,因此应优先选择 throw。
  6. 【关键点 1】throw 保留原始堆栈跟踪,throw ex 重置堆栈跟踪起点。
  7. 【关键点 2】推荐使用 throw,避免使用 throw ex。
  8. 【关键点 3】若要添加信息,可创建新异常并设置内部异常。
  9. 【易错点 1】使用 throw ex 会丢失原始异常抛出位置,增加调试难度。
  10. 【易错点 2】重抛异常时不要吞掉原始异常,应保留堆栈。