还有人在 C# 中使用 [goto] 吗?如果是的话为什么?

发布于 2024-11-18 04:16:57 字数 1432 浏览 3 评论 0原文

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

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

发布评论

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

评论(8

花开柳相依 2024-11-25 04:16:57

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

goto 的常见用途是将控制转移到特定的 switch-case 标签或 switch 语句中的默认标签。

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

下面是后一个问题的示例:

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

end_of_loop:

当然,还有其他方法可以解决这个问题,例如将代码重构为函数、在其周围使用虚拟块等(请参阅 此问题了解详细信息)。附带说明一下,Java 语言设计者决定完全禁止 goto 并引入带标签的 break 语句。

There are some (rare) cases where goto can actually improve readability. In fact, the documentation you linked to lists two examples:

A common use of goto is to transfer control to a specific switch-case label or the default label in a switch statement.

The goto statement is also useful to get out of deeply nested loops.

Here's an example for the latter one:

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

end_of_loop:

Of course, there are other ways around this problem as well, such as refactoring the code into a function, using a dummy block around it, etc. (see this question for details). As a side note, the Java language designers decided to ban goto completely and introduce a labeled break statement instead.

挽清梦 2024-11-25 04:16:57

我记得这部分

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;
}

请参阅 这个

I remember this part

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; 
}

To something like this

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

Refer This

你与清晨阳光 2024-11-25 04:16:57

我在 Eduasync 中广泛使用它来显示编译器在使用异步方法时为您生成的代码类型C# 5。您会在迭代器块中看到同样的事情。

但在“正常”代码中,我不记得上次使用它是什么时候......

I use it extensively in Eduasync 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...

海之角 2024-11-25 04:16:57

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

请参阅 迭代器块实现细节:自动生成的状态机 了解有关 C# 编译器为何/如何处理此问题的更多详细信息

除了生成的代码之外,没有充分的理由使用 goto 语句 - 它使代码更难理解,因此更容易出错;另一方面,在生成的代码中使用 goto 语句可以简化生成过程。过程并且通常很好,因为没有人会阅读(或修改)生成的代码,并且不会因为机器正在编写而出现错误。

请参阅被视为有害的转到声明,了解反对 goto 以及编程史上的经典片段。

The compiler uses goto statements in various pieces of generated code, for example in generated iterator block types (generated when using the yield return keyword - I'm pretty sure that the generated XML serialisation types also have a few goto statements in there somewhere too.

See Iterator block implementation details: auto-generated state machines for some more details on why / how the C# compiler handles this.

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.

See Go-to statement considered harmful for an argument against goto as well as a classic piece of programming history.

孤独难免 2024-11-25 04:16:57

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

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

话又说回来,一个简单的 while (true) 就足够了...

此外,您可以在需要第一次迭代的情况下使用从循环中间开始的循环:look 此处为例。

I don't remember ever using goto. But maybe it improves the intent of a forever loop that you really never want to exit (no break, but you can still return or throw):

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

Then again, a simple while (true) should suffice...

Also, you could use in a situation where you want the first iteration of a loop to start in the middle of the loop: look here for an example.

穿透光 2024-11-25 04:16:57

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

goto is great for breaking out of many loops where break would not work well (say upon error conditions), and as Kragen said goto is used by the compiler to generate switch statements and some other things as well.

各空 2024-11-25 04:16:57

处理器至少实现一个跳转指令并且我确信有很多语句在其实现或解释中使用它们。

使用 3rd第四代 语言是这些物理细节从我们身上抽象出来。虽然我们应该注意泄漏抽象定律,但我认为我们也应该使用我们的工具的用途抱歉)。如果我正在编写代码并且 goto 似乎是个好主意,那么就该重构了。结构化语言的目的是避免这些“跳跃”并在我们的工程中创建逻辑流程。

我应该避免使用 break 但我不能忽视性能优势。但是,如果我有相互需要中断的嵌套循环,那么就该重构了。

如果有人可以建议使用似乎比重构更好的 goto,我会很乐意撤回我的答案。

我希望我没有因为冲向“自行车棚而感到内疚“ 这里。就像 Kragen 所说,对 Dijkstra 来说足够好的对我来说就足够了。

The processor implements at least one jump instruction and I'm sure lots of statements use those in thier implementation or interpretation.

One of the good things about using a 3rd or 4th generation langauge is that these physical details are abstracted away from us. Whilst we should be mindful of the law of leaky abstraction I think that we should also use our tools as they are intended (sorry). If I were writing code and a goto seemed like a good idea, it would be time to refactor. The purpose of a structured language is to avoid these "jumps" and to create a logical flow in our engineering.

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.

I hope I'm not guilty of rushing to the "bike shed" here. Like Kragen says, whats good enough for Dijkstra is good enough for me.

养猫人 2024-11-25 04:16:57

后藤再好不过了。 continue、break(除 switch/case 外)、(多次)return 和 throw 也应保持在最低限度。你永远不想逃离嵌套循环的中间。您总是希望循环控制语句拥有所有循环控制权。缩进包含信息,而所有这些语句都会丢弃该信息。您不妨删除所有缩进。

Goto is never better. And continue, break (except in switch/case), (multiple) return, and throw should also be kept to the barest minimum. You never want to escape from the middle of nest loops. You always want the loop control statements have all the loop control. Indenting has information, and all these statement throw that information away. You might as well take out all the indenting.

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