Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
还有人在C#中使用[goto]吗?如果有,为什么?_C#_.net_Coding Style_Goto - Fatal编程技术网

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

还有人在C#中使用[goto]吗?如果有,为什么?,c#,.net,coding-style,goto,C#,.net,Coding Style,Goto,我想知道是否还有人在C#中使用“goto”关键字语法,以及这样做的可能原因 我倾向于将任何导致读者跳过代码的语句视为不好的做法,但我想知道是否存在使用这种语法的可信场景 编译器在生成的各种代码中使用goto语句,例如在生成的迭代器块类型中(使用yield return关键字时生成)-我非常确定生成的XML序列化类型中也有一些goto语句 有关C#编译器为何/如何处理此问题的更多详细信息,请参阅 除了生成的代码之外,在普通代码中使用goto语句并没有什么好的理由,因为它会使代码更难理解,因此更容易

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

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


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

有关C#编译器为何/如何处理此问题的更多详细信息,请参阅

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

请参阅,以获取反对goto的论点以及一段经典的编程历史。

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

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

goto语句对于摆脱深度嵌套的循环也很有用

下面是后一个例子:

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

end_of_loop:

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

goto非常适合在break无法正常工作的情况下(比如在出现错误的情况下)中断许多循环,正如Kragen所说,goto被编译器用来生成switch语句和其他一些东西。

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

但在“普通”代码中,我记不起上次使用它的时间了…

我记得这部分

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

请参阅

处理器至少实现了一个,我确信许多语句在其实现或解释中使用了这些语句

使用一代或一代语言的好处之一是这些物理细节从我们身上抽象出来。虽然我们应该注意,但我认为我们也应该使用我们的(对不起)。如果我在编写代码,而转到
似乎是个好主意,那就是重构的时候了。结构化语言的目的是避免这些“跳跃”,并在我们的工程中创建逻辑流

我应该避免使用
break
,但我不能忽视性能方面的好处。但是,如果我有嵌套循环,它们相互需要
break
,那么是时候重构了

如果有人提议使用
goto
,这似乎比重构更好,我会很乐意收回我的答案


我希望我没有因为冲到这里的“”而感到内疚。就像Kragen说的,足够好的东西对我来说就足够了。

我不记得曾经使用过
goto
。但它可能会改善你真的永远不想退出的循环的意图(没有
中断
,但你仍然可以
返回
抛出
):

再说一次,一个简单的
while(true)
就足够了


也可以在一个循环中第一次迭代的情况下使用:在循环的中间:寻找一个例子。

Goto永远不会更好。return和throw也应该保持最小值。你永远不想从嵌套循环的中间逃脱。你总是希望循环控制语句拥有所有的循环控制。缩进有信息,所有这些语句都会丢弃这些信息。你最好去掉所有缩进。

通常我会尝试重构或者将循环放在一个单独的方法中,我可以从…@Heinzi返回-我没有看到goto被担保。就像Jon说的,如果它被“担保”,代码正在请求重构。标记为break,这是一种更长的说法,表示goto,因为它做了同样奇怪的事情…@Jesus,但是有了goto,你可以去任何地方。标记为break确保你只是在循环之外。除非你很冒险,并且使用带有地址的goto(我以前见过这样做)然后问题就缓解了。我怀疑有人在C#和Java代码中使用迂回钩子来利用goto语句。当然是“中断”/“继续”是更好的方法来循环管理,而不是要求代码编辑器跳过源代码,试图了解下一步发生的位置?如果不是嵌套的循环,OK,我可以将其视为一个有效的场景。在错误情况下,您应该考虑抛出异常。如果您想在没有EXC的情况下在内部处理错误。这是一种有效的方法。你能举一个小例子说明为什么喜欢这种方法,或者这仅仅是个人的喜好吗?@Brian:你的意思还不太清楚。Eduasync显示了编译器为你所做的等价的C代码,它生成的代码有效地使用了goto…我实际上把这看作是一个任务这是使用[goto]的一个正当理由。至少在这种情况下,它提高了程序员的可读性,使他们不知道案例之间没有中断语句就互相插入了。@Brian Scott,V4Vendetta。除非我弄错了
forever: {
  // ...
  goto forever;
}