还有人在 C # 中使用[ goto ]吗? 如果有,原因是什么?

我想知道是否还有人在 C # 中使用“ goto”关键字语法,以及这样做的可能原因是什么。

我倾向于认为任何导致读者跳过代码的语句都是不好的做法,但是我想知道是否存在使用这种语法的可信场景?

关键字定义

103018 次浏览

编译器在生成代码的各个部分中使用 goto语句,例如在生成的迭代器块类型中(使用 yield return关键字生成的)——我很确定生成的 XML 序列化类型中也有一些 goto语句。

有关 C # 编译器为什么/如何处理这个问题的更多细节,请参见 迭代器块实现细节: 自动生成的状态机

Other than generated code there isn't a good reason to use a goto statement in normal code - it makes the code harder to understand and as a result more error-prone. On the other hand using goto statements in generated code like this can simplify the generation process and is normally fine because nobody is going to read (or modify) the generated code and there is no chance of mistakes being made because a machine is doing the writing.

有关反对 goto的参数以及经典的编程历史,请参阅 被认为有害的即时陈述

在一些(罕见的)情况下,goto 实际上可以提高可读性。事实上,您链接到的文档列出了两个例子:

Goto 的一个常见用法是将控制权转移到特定的 switch-case 标签或 switch 语句中的默认标签。

Goto 语句对于跳出深度嵌套循环也很有用。

下面是后者的一个例子:

for (...) {
for (...) {
...
if (something)
goto end_of_loop;
}
}


end_of_loop:

当然,还有其他方法可以解决这个问题,比如将代码重构为一个函数,在它周围使用一个虚块,等等(详见 这个问题)。作为附带说明,Java 语言设计人员决定完全禁止 Goto,而是引入 标记为休息时间语句。

Goto 非常适合打破许多循环,而这些循环中的 break 不能很好地工作(比如在错误条件下) ,正如 Kragen 所说,goto 被编译器用来生成 switch 语句和其他一些东西。

I use it extensively in 教育异步 to show the kind of code that the compiler generates for you when using async methods in C# 5. You'd see the same thing in iterator blocks.

In "normal" code though, I can't remember the last time I used it...

我记得这段

switch (a)
{
case 3:
b = 7;
// We want to drop through into case 4, but C# doesn't let us
case 4:
c = 3;
break;
default:
b = 2;
c = 4;
break;
}

这样的事情

switch (a)
{
case 3:
b = 7;
goto case 4;
case 4:
c = 3;
break;
default:
b = 2;
c = 4;
break;
}

Refer 这个

处理器实现了至少一个 跳跃指令跳跃指令,我相信很多语句在它们的实现或解释中都使用了它们。

使用 第三名四年级生成语言的好处之一是,这些物理细节是从我们这里抽象出来的。虽然我们应该留意的 抽象漏洞定律我认为,我们也应该使用我们的 工具(抱歉)。如果我正在编写代码,而 goto似乎是个好主意,那么现在就是重构的时候了。结构化语言的目的是避免这些“跳跃”,并在我们的工程中创建一个逻辑流。

I should avoid the use of break but I can't overlook the performance benefit. However, if I have nested loops that mutually need to break it is time to refactor.

If anybody can propose a use of goto that seems better than refactoring I will gladly withdraw my answer.

我希望我没有因为急着去看“ 自行车棚”而感到内疚。就像 Kragen 说的,对 Dijkstra来说足够好的东西对我来说也足够好。

我不记得我用过 goto。但是 也许吧改善了永久循环的意图,你真的永远不想退出(没有 break,但你仍然可以 returnthrow) :

forever: {
// ...
goto forever;
}

不过,一个简单的 while (true)就足够了。

此外,在希望循环的第一次迭代从循环中间开始的情况下,可以使用 可以: 查看 here的示例。

后藤再好不过了。继续,中断(除了开关/情况下) ,(多次)返回,扔也应该保持在最低限度。你永远不会想从巢穴循环的中间逃走。您总是希望循环控制语句具有所有的循环控制。缩进包含信息,所有这些语句都会丢弃这些信息。你最好把所有的凹痕都去掉。