编写仅包含 throw 语句的 catch 块是否有任何技术原因?

Is there any technical reason to write a catch block containing only a throw statement?

免责声明:众所周知catch (ex) { throw ex; } is bad practice。这个问题不是


在挖掘 Microsoft 参考资源时,我注意到 a lot of methods 中存在以下模式:

try {
    ...
} catch {
    throw;
}

没有日志记录,没有调试代码——只是一个简单的 catch { throw; }

既然 Microsoft 的人显然应该相当精通 C# 的使用,那么这样做而不是完全省略 catch 块(和 try 语句)的意义何在? 像这样编码是否有技术原因,还是纯粹是风格选择?

注意:我不知道它是否相关,但我能找到的所有此类实例还包含嵌套在 [=14= 中的 try-finally 块] try-catch 块的子句。

您链接的代码实际上是一个很好的例子。

在我看来,在处理超出他们控制范围的事情时,应该只使用 try catch 块,例如文件系统,基本上是外部事物。

在您链接的代码中,try catch 与数据库有关。

这意味着通过使用这种编码方式,他们可以确保没有泄漏,没有连接保持打开状态。

如果出现任何问题,例如错误的连接字符串、丢失的表等等,代码将继续执行,它将优雅地关闭连接,如 finally[=25= 所示] 块,它最终将抛出意味着它将允许该代码的客户端获得适当的异常,也获得整个堆栈并让他们决定在发生这种情况时要做什么。

老实说,我很喜欢他们在那里所做的。

它影响何时过滤异常 运行。

给定

void f() {
  using (var x = AcquireResource()) {
    x.DoSomething();
    x.DoSomethingElse();
  }
}

对比

void f() {
  try {
    using (var x = AcquireResource()) {
      x.DoSomething();
      x.DoSomethingElse();
    }
  } catch {
    throw;
  }
}

void g() {
  try {
    f();
  } catch (Exception ex) when (h()) {
    // ...
  }
}

f 的第一个版本将允许在 x 被释放之前调用过滤器 h()f 的第二个版本确保在外部代码 运行.

之前处理 x

在你link的代码中,SqlConnectionHolder用的比较多,而catch { throw; }块都是围绕着SqlConnectionHolder.

的使用

C# Specification所述:

When an exception occurs, the system searches for the nearest catch clause that can handle the exception, as determined by the run-time type of the exception. First, the current method is searched for a lexically enclosing try statement, and the associated catch clauses of the try statement are considered in order. If that fails, the method that called the current method is searched for a lexically enclosing try statement that encloses the point of the call to the current method. This search continues until a catch clause is found that can handle the current exception, by naming an exception class that is of the same class, or a base class, of the run-time type of the exception being thrown. A catch clause that doesn't name an exception class can handle any exception.

Once a matching catch clause is found, the system prepares to transfer control to the first statement of the catch clause. Before execution of the catch clause begins, the system first executes, in order, any finally clauses that were associated with try statements more nested that than the one that caught the exception.

如果出现异常,运行时首先查找可以处理它的 catch 子句,这涉及执行任何关联的异常过滤器。不加区分的 catch 块中断搜索并使所有嵌套的 finally 块立即执行。

当你想阻止调用者在 finally 块之前执行任意代码(以异常过滤器的形式)时,这会很有用。例如,当 finally 块影响当前线程的安全上下文时。

此外,如果异常不会被任何catch 子句捕获,则会导致线程终止。在这种情况下,C# 规范不提供任何保证,任何 finally 块都将被执行。

If the search for matching catch clauses reaches the code that initially started the thread, then execution of the thread is terminated. The impact of such termination is implementation-defined.