C#中的标签有什么用?

时间:2009-03-19 15:14:33

标签: c#

标签和GOTO被认为是不好的做法,据我所知,没有理由在C#中使用它。

C#中标签的用途是什么?

13 个答案:

答案 0 :(得分:20)

标签和goto本身没有任何问题。问题是人们倾向于滥用它们确实会产生问题。

标签的典型用途

OperationStart:
  if ( !TrySomeOperation() ) {
    if ( MaybeFixOperation() ) { 
      goto OperationStart;
    }
  }

你需要做一些你无法触及infitite循环的断言,但是给出一套合理的保证,这段代码没有任何内在错误。

答案 1 :(得分:8)

仅仅因为他们是一个声名狼借的做法,并不意味着应该关闭使用它们的任何可能性。虽然他们可能永远不会需要,但偶尔也是最好的方式。

答案 2 :(得分:6)

当您实现较小的finite state machine时,您可以为每个州使用标签,并使用 goto 进行状态转换。这是植入有限状态机的标准方法之一,并且可以导致清晰的代码,前提是代码注释指向的文档中有状态机图。

有时问题域包含许多状态机(例如电信协议通常由有限状态机定义),大多数情况下你经常看不到有限状态机。

Gotos 标签对于机器生成的代码也非常有用,如果您正在编写一个输出C#的简单编译器,您可能会对它们感到非常高兴。

答案 3 :(得分:3)

代码生成器有时会使用标签和gotos。在某些情况下,它可以简化代码生成逻辑。由于可读性原因,Goto语句通常被避开,但如果不打算读取代码那么这是一个有争议的问题。

我还看到过反编译器被IL充分混淆并输出goto语句而不是人类会想到的精心设计的指令序列的情况。如果goto语句不合法,那么反编译器可能不得不完全放弃该段代码。这样,至少,它可以生成可以往返的某事

答案 4 :(得分:2)

我认为这是一个营销决策..

Microsoft希望各种开发人员使用他们的C#语言,如果添加标签,它会让一些程序员更容易转换。它还可以更容易地将旧代码移植到他们的语言中......

答案 5 :(得分:2)

没有goto的标签没用,它们什么都不做。

使用goto被认为是一种不好的做法。但有一种情况是无法避免的:打破嵌套循环:

foreach(...) {
  foreach(...) {
    if(...) {
      goto OuterLabel;
    }
  }
}
OuterLabel:

在这种情况下,使用break语句只会破坏最内层循环。

答案 6 :(得分:2)

为什么会出现?

原因其实很简单。汇编程序和IL不支持高级指令,如fordobreakcontinuewhile。隐式地,循环(或更一般地说:分支)的代码被编译为分支。 gotolabel是一个非常直接的分支。

请注意,如果没有'goto',你根本无法实现我能够轻松想到的所有装置 - 尽管通常有更好的选择(此时我想指出有类似{的设计模式{1}})。

如果你设计一种类似C#的语言,它是“IL的高级汇编程序”,那么至少支持IL中的所有内容是有意义的。这里,branch / label是低级构造,goto / label是C#projection(范围被添加为高级构造)。

来自编译器POV

最后,如果您了解编译器的工作原理,可预测的代码和不可预测的代码会有所不同。编译器的优化部分花费了大量精力来规范您在代码中使用的构造。一旦标准化,它就会使用模式进行优化。

这就是问题所在。如果您有State pattern循环,while循环或for循环,它肯定会生成标准化模式。毕竟,循环是代码中可以优化的第一件事。但是,如果您使用的是奇怪的分支,那么将不会进行优化 - 只是因为它不会被标准化为标准化模式,因此不会被模式匹配器拾取。< / p>

此评论不仅涉及代码模式的可预测性 - 它还涉及数据流的可预测性。同样,如果它是可预测的,那么你的编译器可以做得更多,而不是它。在各种情况下,像foreachbreak这样的结构也会导致更多不可预测的分支;标签和continue将让您更轻松地到达那里。结果是一样的:如果发生这种情况,你的表现会受到影响。

因此,所有编译器确实将循环更改为特定表单的分支。 IL编译器是一个SSA编译器,就像LLVM一样。钱德勒的这段视频解释了一两件关于它是如何工作的:https://www.youtube.com/watch?v=FnGCDLhaxKU

答案 7 :(得分:1)

如果没有它们,很难做出切换语句。

答案 8 :(得分:0)

我在某处读过,在大多数情况下,goto应该只用于向前跳转,因此很可能仅用于早期循环终止和继续外循环,因为C#中没有标记循环(与Java不同)。并且有一些算法可以用goto优雅地表达,而不是以结构化的方式表达。

答案 9 :(得分:0)

有时候,'goto'比其他技术更优雅/可读。把'goto'放在不需要的地方当然是一种不好的做法。一如既往,应仔细判断每种情况。

例如,当你的函数需要进行清理以防万一它失败时,'goto'会很好。在函数的末尾放置一个标签,在那里进行清理,然后在发生故障时“转到”它。

尽管如此,'goto在C#中的用处不如在C中。例如,在某些情况下,正确使用异常处理可以避免使用'goto'。

答案 10 :(得分:0)

使用标签是为了支持gotogoto可能不正确,如果您的语言中有goto,那么您需要标签。如果没有goto,标签在C#中确实无用。

答案 11 :(得分:0)

虽然原则上我认为goto语句有合法用途,但实际上我一直在使用C#进行开发,因为它首次发布,我不知道到目前为止goto声明。

答案 12 :(得分:0)

if(audience.LikesGoTo == true) {    转到LabelThatSupportGoTo; } 其他 {    转到LabelForRejectGoTo; }