C#.NET中的GOTO语句

8
try
{...
block:
....
}
catch{ ..}
GOTO block
...
....
finally{...}

这种情况下,goto会执行吗?

2
这不是编译错误吗? - ironic
3
也许它应该被称为“意面.NET”。;-) - apaderno
1
为什么会有人踩?是的,也许他应该尝试编译一下,但我认为这些踩并不应该。 - Andreas Bonini
@Pondidum 如果这个能够工作,它可以用来模拟 VB.NET 的 On Error Resume Next。 - R.J. Dunnill
2个回答

16
由于使用了 'GOTO block' 而不是 'goto block;',即使语法正确也无法编译通过,因为 C# 规范 (§8.9.3) 规定:goto 语句的标签是具有给定名称的标记语句。如果当前函数成员中不存在具有给定名称的标记,或者 goto 语句不在标记的范围内,则会发生编译时错误。此规则允许使用 goto 语句将控件从嵌套作用域转移出来,但不能转移到嵌套作用域内部。
此外,我还发现了一些对我有趣的规范:
一个 goto 语句不能离开 finally 块 (§8.10)。当一个 goto 语句出现在 finally 块中时,goto 语句的目标必须在同一 finally 块内,否则会发生编译时错误。
并且:
goto 语句的执行过程如下:
- 如果 goto 语句退出一个或多个具有关联 finally 块的 try 块,则控制最初转移到最内层 try 语句的 finally 块。当控制到达 finally 块的结束点时,控制转移到下一个封闭 try 语句的 finally 块。这个过程会一直重复,直到执行所有介于 try 语句的 finally 块。 - 控制转移到 goto 语句的目标。
后者意味着如果您有这样的代码:
try
{
    ...
    goto Label1;
}
finally
{
    CloseAll();
}

Label1:
   MethodB();

在实际转移控制并执行MethodB()之前,它将调用CloseAll()

听起来很合理,但我从未想过...


goto语句不应该出现在finally语句块内。 - Fortega
其实我没太关注语法.. 我从你的回答中得到了我想要的 谢谢 - Kiran Thokal

6

编号块:标签必须放在try的外面,以便goto能够看到它。代码甚至无法编译。你是在参加测试吗?


不好意思,其实是我的朋友问了我这样的问题,让我感到困惑,所以我想在Stackoverflow上问一下。 - Kiran Thokal
我发现在这种情况下阅读C#语言规范非常有启发性 :) - Regent
2
当然,在Visual Studio中实际尝试代码会给您很多信息。 - Lasse V. Karlsen
1
@Regent:启发性+深思熟虑=启发深刻。 :D - Matt Ellen
说真的,有人会看那些规范吗?直接测试不是更容易吗? - erikkallen
1
@erikkallen 我怀疑在这里给出最好回答的人已经阅读了规格说明书 :-) - James Hopkin

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