C# 中的 try catch 块

5

我在项目中使用了try catch和finally块。我的疑问是,为什么我们需要使用finally块,实际上如果不使用finally块,那么代码也会在catch块后执行。因此,我们可以在catch块后编写代码(以释放资源)。即使发生异常,这些代码也将被执行。那么,如果我们使用finally块,是否有任何优势呢?


可能是为什么在C#中使用finally?的重复问题。 - John Saunders
7个回答

7
根据这个之前的SO帖子的回答:

无论是否发生异常,finally块中的代码都将被执行。当需要始终运行某些类似于关闭连接的清理函数时,这非常有用。


1

我想你在谈论这个:

try {
  // do something that might throw exception
}
catch (Exception) {
  // take care of exception
}
finally {
  // what is the point of this?
}

如果您在catch块中处理了所有可能的异常,那么您可能需要一个finally块来拦截try块内部的return语句。
感谢@dthorpe: finally还将拦截catch块内部的任何异常/返回语句。

3
如果从 catch 块中抛出异常,那么最终代码块也会被执行。 - dthorpe

1

只有在抛出异常时,代码才会在 catch 块中执行。

如果抛出异常或未抛出异常,代码将在 finally 块中执行。由于您可以依赖 finally 块始终执行,无论是否抛出异常,因此 finally 块是您应该清理任何资源的地方,特别是非托管资源,例如文件或操作系统句柄。

您提到依赖 catch 块后执行代码来释放资源。这不是一个安全的假设,因为 a) 适当限制的 catch 块不会捕获所有异常,而只是代码需要处理的异常,b) catch 块本身可能会抛出或重新抛出异常。catch 块后面的代码可能不会被执行。

如果您习惯编写未经限定的 catch 块来捕获并消除所有异常,则滥用了异常。


+1 是为了解释滥用的情况,以及 catch 和 finally 是两个根本不同的东西。我希望更多的编程语言能够禁止在同一语句中使用 catch 和 finally... - Jeroen Wiert Pluimers

0

想象一下这个用法:

String doSomething()
{
  SqlConnection conn;

  try {
    conn = new SqlConnection();

    // SQL stuff

    return result;
  }
  catch(Exception ex) { AddToLog(ex);  }
  finally {
    if (conn != null)
      conn.Dispose();
  }

  return null;
}

无论 SQL 部分发生什么,您始终会正确处理。

0

在发生异常时,您应该使用finally块来释放未托管的资源。您还可以处理在“try”中构造的任何可处置类型的GC或Dispose。


0
无论是否发生异常,finally块都会被执行。因此,您可以在finally块中关闭数据库连接或其他Dispose活动。

我不明白为什么有人会在不留言的情况下给踩。 - FIre Panda

0

这实际上取决于你如何使用它,如果你只有空的catch块,那么是否有finally块都不会有任何区别。在处理一些catch块中的内容并且还希望在catch之后执行一些代码的情况下,它非常优雅。

然而,try/catch/finally是为异常情况设计的,需要为最坏的情况做好准备,以使您的程序更加健壮。如果其中一个catch处理程序重新抛出异常,则catch块后面的代码(不在finally块中)将永远不会被执行。

由于在某些特定情况下代码很可能不会被执行,因此finally块是执行所需关键操作的保险。您需要识别这种情况,并没有规定每个try catch块都必须有finally。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接