在最后一个块中返回...为什么不呢?

发布于 2024-11-03 02:57:15 字数 682 浏览 4 评论 0原文

正如 MSDN 提及

Finally 块中的代码在 Try 或 Catch 中的 Return 语句 遇到块,但在此之前 返回语句执行。在这个 情况下,Return 语句 finally 块在 初始返回语句。这给出了 返回值不同。为防止 这种可能令人困惑的情况, 避免使用 Return 语句 最后阻塞。

由于我从这篇文章中没有理解很多内容,我将举一个例子(VB.NET,我认为在 C# 中情况是类似的):

Try
    HugeOp()
    Return "OK"
Catch
    Return "NOK"
Finally
    Return "Finally"
End Try

现在,为什么这在两者中都是非法的 C# 和 VB.NET?

As MSDN mentions:

The code in a Finally block runs after
a Return statement in a Try or Catch
block is encountered, but before that
Return statement executes. In this
situation, a Return statement in the
Finally block executes before the
initial Return statement. This gives a
different return value. To prevent
this potentially confusing situation,
avoid using Return statements in
Finally blocks.

As I didn't understand a lot from this note, I'll take an example (VB.NET, I think in C# is the situation is similar):

Try
    HugeOp()
    Return "OK"
Catch
    Return "NOK"
Finally
    Return "Finally"
End Try

Now, why should be this illegal in both C# and VB.NET?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

孤千羽 2024-11-10 02:57:15

这是非法的,因为当您到达 Finally 块时,要返回的值已经定义(如果一切顺利,则返回“OK”;如果捕获异常,则返回“NOK”)。如果您能够从 Finally 块返回不同的值,则无论上述指令的结果如何,都将始终返回该值。这只是没有意义...

It's illegal because when you reach the Finally block, the value to return is already defined ("OK" if everything went well, "NOK" if an exception was caught). If you were able to return a different value from the Finally block, this value would always be returned, whatever the outcome of the instructions above. It just wouldn't make sense...

骷髅 2024-11-10 02:57:15

我想答案就在问题里。这是非法的,因为它令人困惑。将返回哪个值并不直观。如果它是非法的,您将被迫编写流程更清晰的代码。

I guess the answer is in the question. It's illegal because it's confusing. It's not intuitive which value will be returned. If it's illegal, you are forced to write code where the flow is much clearer.

走野 2024-11-10 02:57:15

我对此很好奇,我正在运行 VS2010 并且不允许在 finally 块中返回。这是我编译的代码

Public Class Class1
   Public Shared Function test() As String
      Try
         Return "OK"
      Catch ex As Exception
         Return "Catch"
      Finally
         test = "Finally"
      End Try
   End Function
End Class

我编译了 DLL 以查看 MSIL,它看起来相当有趣,上面的代码基本上被重构为:

Public Class Class2
   Public Shared Function test() As String
      Try
         Try
            test = "OK"
         Catch ex As Exception
            test = "Catch"
         End Try
      Finally
         test = "Finally"
      End Try

      Return test
   End Function
End Class

并进行测试,上面两个类的 MSIL 完全相同。

I was curious about this, I'm running VS2010 and does not allow a Return in the finally block. here is the code I compiled

Public Class Class1
   Public Shared Function test() As String
      Try
         Return "OK"
      Catch ex As Exception
         Return "Catch"
      Finally
         test = "Finally"
      End Try
   End Function
End Class

I compiled the DLL to view the MSIL it looked rather interesting the above code basically gets refactored to this:

Public Class Class2
   Public Shared Function test() As String
      Try
         Try
            test = "OK"
         Catch ex As Exception
            test = "Catch"
         End Try
      Finally
         test = "Finally"
      End Try

      Return test
   End Function
End Class

and testing this out, the MSIL for the above two classes is exactly the same.

踏雪无痕 2024-11-10 02:57:15

finally 块中不允许使用 return 语句的原因最终归结为这些结构的要点/目标。

Finally 块是特殊的代码块,旨在始终在某些先前的控制结构完成执行之后从头到尾运行;它们主要用于“清理”类型的代码。

如果我们采用提供的代码:

Try
    HugeOp()
    Return "OK"
Catch
    Return "NOK"
Finally
    Return "Finally"
End Try

Finally 块将ReturnTry执行 > 或 Catch

这确实意味着有一个 Return 会“总是返回相同的东西”,但它不仅如此 - 一个 Return 已经发生在当前程序中!该指令究竟意味着什么?我们要回到哪里?

在一般情况下,ReturnFinally 中没有任何意义,因为有一条将控制权转移到这些块之外的语句 1) 与它们的目的相反,2) 很难甚至概念化,因为 Finally 块在运行时打破了“标准”控制流,因为它们出现在某些先前控制结构的 Return 之后。

在 C# 中,finally 块中不允许使用 goto,原因基本相同:在设计上,外部控制传输在 finally 内是禁止的。


JavaScript 可以作为一个例子,说明如果没有这条规则,事情会变得多么混乱: 在 JS 中,finally 块在控制流语句之前立即执行(例如 return代码>) 中try/ catch,但do允许return在其内部 - 这将掩盖(覆盖)try/ catch 中返回(如果存在)。

我认为,除了彻底禁止它之外,没有任何解决方案可以使问题变得混乱。

The reason that return statements aren't allowed in finally blocks ultimately comes down to the point/ goal of those structures.

Finally blocks are special blocks of code intended to always run start to finish, after some previous control structure has finished executing; they're primarily for "cleanup"-type code.

If we take the code provided:

Try
    HugeOp()
    Return "OK"
Catch
    Return "NOK"
Finally
    Return "Finally"
End Try

The Finally block will be executed after the Return from either the Try or Catch.

This does kind of mean that having a Return there would "always return the same thing", but it's more than that– a Return already happened in the current procedure! What should that instruction even mean? Where are we returning to?

In the general case, a Return makes no sense within a Finally because having a statement that transfers control outside of these blocks is 1) antithetical to their purpose, and 2) hard to even conceptualize, since Finally blocks break the "standard" control flow when they run since they come after the Return of some previous control structure.

In C#, gotos are disallowed in finally blocks for essentially the same reason: external control transfer is just off limits within finally by design.


JavaScript can serve as an example here of how confusing things could be without this rule: in JS, finally blocks execute immediately before a control-flow statement (e.g. return) in try/ catch, but do allow returns inside themselves– which will overshadow (override) the return inside the try/ catch, if it exists.

I'd argue there's no resolution to this problem that's not confusing, other than just outright disallowing it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文