转到声明被认为有害吗?

Yar*_*veh 16 .net c# goto base-class-library

如果上面的陈述是正确的,那么为什么当我在.Net BCL上使用反射器时,我看到它被大量使用了?

编辑:让我重新说一下:我在人类或编译器编写的反射器中看到的所有GO-TO是什么?

Cra*_*gTP 24

我认为以下关于Goto维基百科文章的摘录这里特别相关:

可能最着名的批评GOTO的是1968年由Edsger Dijkstra写的一封名为Go To Statement Considered Harmful的信.在那封信中,Dijkstra认为不应该从高级语言中废除不受限制的GOTO语句,因为它们使分析和验证程序正确性(特别是那些涉及循环)的任务变得复杂.Donald Knuth的结构化编程中提供了另一种观点,即转到语句,该语句分析了许多常见的编程任务,并发现其中一些GOTO是使用的最佳语言结构.

因此,一方面我们有Edsger Dijkstra(一位非常有才华的计算机科学家)反对使用该GOTO声明,并特别反对过度使用该GOTO声明,理由是它是一种结构化程度较低的编写方式.

另一方面,我们有Donald Knuth(另一位非常有才华的计算机科学家)认为使用GOTO,特别是明智地使用它实际上可以成为给定程序代码的"最佳"和最佳构造.

最终,恕我直言,我相信这两个人都是正确的.Dijkstra是正确的,因为过度使用GOTO语句肯定会使一段代码的可读性和结构性降低,从纯理论角度查看计算机编程时,这当然是正确的.

然而,Knuth也是正确的,因为在"现实世界"中,必须采用务实的方法,GOTO明智地使用语句确实可以成为语言构造的最佳选择.

  • +1:这是我在这个帖子中读到的最平衡的答案,并且它没有歪曲Dijkstra所写的内容. (2认同)

小智 19

以上并不是真的正确 - 它是Dijkstra使用的一个争论设备,当时gotos是关于唯一使用的流量控制结构.事实上,有几个人已经制作了反驳,包括Knuth经典的"使用Goto进行结构化编程"论文(记忆中的标题).并且有一些情况(错误处理,状态机),其中gotos可以产生比"结构化"替代品更清晰的代码(恕我直言).

  • 它甚至不是Dijkstra的论战设备.正如维基百科的文章指出他没有选择该论文的标题.讽刺他应该为这个头衔而闻名. (4认同)
  • 所以@Neil,为了清楚起见,这是你的立场,如果一个编辑改变你的文章的标题并发布它而不先由你运行它,你是负责任的,没有其他人负责.是? (4认同)

Joh*_*lph 11

这些goto通常由编译器生成,尤其是在枚举器内部.编译器总是知道她在做什么.

如果您发现自己需要使用goto,则应确保它是唯一的选择.大多数情况下,你会发现有更好的解决方案.

除此之外,很少有实例goto可以证明是合理的,例如使用嵌套循环时.同样,在这种情况下还有其他选择.您可以在函数中分解内部循环并使用return语句.您需要仔细查看附加方法调用是否真的太昂贵.


为了回应您的编辑:

不,并非所有的getos都是编译器生成的,但是很多都是由编译器生成的状态机(枚举器),switch case语句或优化的if else结构产生的.只有少数几个实例可以判断它是编译器还是原始开发人员.您可以通过查看函数/类名来获得良好的提示,编译器将生成"禁用"名称以避免与您的代码发生名称冲突.如果一切看起来正常并且代码未经过优化或混淆,则可能会使用goto.

  • 编译器总是知道她在做什么**.如此挑剔的东西一定是女性. (8认同)
  • @Nifle:修复.:-) (2认同)

Jam*_*ran 8

请记住,您在Reflector中看到的代码是反汇编 - Reflector正在查看已编译的字节代码并尝试将原始源代码拼凑在一起.

有了这个,您必须记住针对gotos的规则适用于高级代码.所使用的所有构造来取代gotoS( ,for,,while 等)全部采用的JMP向下编译代码.breakswitch

所以,Reflector看起来像这样的代码:

A:
    if !(a > b)
        goto B;
    DoStuff();
    goto A;
B:  ...
Run Code Online (Sandbox Code Playgroud)

并且必须意识到它实际编码为:

 while (a > b)
    DoStuff();
Run Code Online (Sandbox Code Playgroud)

有时,读取的代码太复杂,无法识别模式.