使用 goto 从一个案例跳转到另一个案例
Fall from one case to another using goto
我读过多篇文章说使用 goto 是编程中的大忌。但有些人特别指出滥用 goto 是错误的,并且在某些情况下,例如 switch cases,这是预期的用途。
所以我想问你的问题是,为了将来参考,哪种方法最有效practice/more。
这个:
switch (a)
{
case 1:
//Something specific for case 1
break;
case 2:
//Something specific to default and case 2
break;
default:
//Something specific for default
goto case 2;
}
或者这个:
switch (a)
{
case 1:
//Something specific for case 1
break;
case 2:
//Something specific to default and case 2
thatFunction();
break;
default:
//Something specific for default
thatFunction();
break;
}
void thatFunction() { /*Case 2 stuff*/ }
编辑: 这两个 switch 语句是示例,实际代码包含更多情况。
我工作场所的每个人要么从未使用过 goto,要么只听说从未使用过它。所以我来这里是为了得到一个明确的答案。我正在寻找 answer 和 explanation 或相关链接。
谢谢,
答案是,绕圈子的逻辑最好保留给宗教和政治。你的 default
实际上是 case 2
,这意味着 case 2
实际上只是 default
。虽然 case 2
中可能有一些执行在 default
中没有发生,但极少需要在 [=] 中执行 if
条件以外的任何操作10=] 案例。此外,在排除故障时,如果您向后循环案例链,则无法立即确定 switch
评估的结果。想象一下您的堆栈跟踪。
有 次使用 goto
,但通常在 exception
al 情况下(看看我在那里做了什么)你需要立即在 break
进入 运行 条件或无限循环之前执行一个操作(例如在另一个线程上记录错误)。 goto
的一般规则与预处理器命令相同。如果有另一种方法可以做同样有效的事情,为了逻辑连续性和可维护性,您应该使用另一种方法。
您始终需要了解任何 "no-no"(或 "yes-yes")背后的原因。这样您就可以了解在哪些情况下适用该规则,在哪些情况下不适用。
与 goto
的激烈斗争一直追溯到没有真正的过程和函数,甚至像循环这样简单的东西的编程。 goto
允许您从任何地方跳到其他任何地方,并且很难思考它的实际含义。 "Don't use goto" 是转向结构化代码的一部分,而不是围绕代码一路跳转;使用 for (int i = 10; i > 0; i--) { ... }
之类的东西进行迭代,而不是 if (i-- > 0) goto startLoop;
.
在switch
中,goto
被约束——它只能做一件事,执行switch
语句的一个分支。事实上,在 C# 中,即使在 switch
语句之外,goto
也是非常受限和安全的,并且很少具有 "Goto is evil" 运动开始时假设的任何含义。当然,这并不意味着您应该开始用 goto
替换所有循环 :)
现在,如果事情变得如此复杂,可能是因为 switch
一开始就不是解决问题的好方法。也许你可以使用不同的结构来做你想做的事情——有很多方法可以在 C# 中实现多态性 and/or 代码重用,其中一种可能是更好的方法,可以让你使用更清晰的代码做你想做的事。但我们真的帮不了你 :)
我读过多篇文章说使用 goto 是编程中的大忌。但有些人特别指出滥用 goto 是错误的,并且在某些情况下,例如 switch cases,这是预期的用途。
所以我想问你的问题是,为了将来参考,哪种方法最有效practice/more。
这个:
switch (a)
{
case 1:
//Something specific for case 1
break;
case 2:
//Something specific to default and case 2
break;
default:
//Something specific for default
goto case 2;
}
或者这个:
switch (a)
{
case 1:
//Something specific for case 1
break;
case 2:
//Something specific to default and case 2
thatFunction();
break;
default:
//Something specific for default
thatFunction();
break;
}
void thatFunction() { /*Case 2 stuff*/ }
编辑: 这两个 switch 语句是示例,实际代码包含更多情况。
我工作场所的每个人要么从未使用过 goto,要么只听说从未使用过它。所以我来这里是为了得到一个明确的答案。我正在寻找 answer 和 explanation 或相关链接。 谢谢,
答案是,绕圈子的逻辑最好保留给宗教和政治。你的 default
实际上是 case 2
,这意味着 case 2
实际上只是 default
。虽然 case 2
中可能有一些执行在 default
中没有发生,但极少需要在 [=] 中执行 if
条件以外的任何操作10=] 案例。此外,在排除故障时,如果您向后循环案例链,则无法立即确定 switch
评估的结果。想象一下您的堆栈跟踪。
有 次使用 goto
,但通常在 exception
al 情况下(看看我在那里做了什么)你需要立即在 break
进入 运行 条件或无限循环之前执行一个操作(例如在另一个线程上记录错误)。 goto
的一般规则与预处理器命令相同。如果有另一种方法可以做同样有效的事情,为了逻辑连续性和可维护性,您应该使用另一种方法。
您始终需要了解任何 "no-no"(或 "yes-yes")背后的原因。这样您就可以了解在哪些情况下适用该规则,在哪些情况下不适用。
与 goto
的激烈斗争一直追溯到没有真正的过程和函数,甚至像循环这样简单的东西的编程。 goto
允许您从任何地方跳到其他任何地方,并且很难思考它的实际含义。 "Don't use goto" 是转向结构化代码的一部分,而不是围绕代码一路跳转;使用 for (int i = 10; i > 0; i--) { ... }
之类的东西进行迭代,而不是 if (i-- > 0) goto startLoop;
.
在switch
中,goto
被约束——它只能做一件事,执行switch
语句的一个分支。事实上,在 C# 中,即使在 switch
语句之外,goto
也是非常受限和安全的,并且很少具有 "Goto is evil" 运动开始时假设的任何含义。当然,这并不意味着您应该开始用 goto
替换所有循环 :)
现在,如果事情变得如此复杂,可能是因为 switch
一开始就不是解决问题的好方法。也许你可以使用不同的结构来做你想做的事情——有很多方法可以在 C# 中实现多态性 and/or 代码重用,其中一种可能是更好的方法,可以让你使用更清晰的代码做你想做的事。但我们真的帮不了你 :)