102

当我switch在 VS2008 C# 中创建这样的语句时(人为):

switch (state) {
    case '1':
        state = '2';
    case '2':
        state = '1';
}

它抱怨我不允许通过:

控制不能从一个案例标签 ('case '1' (0x31):') 转移到另一个

如果您不被允许通过,那么该break声明的目的是什么?为什么语言设计者不直接忽略它并自动跳到switch语句的末尾,而不是强迫我们放入不必要的构造?

4

4 回答 4

88

基本上是为了让 C/C++/Java 开发人员更熟悉它。我个人认为这是一个错误,但这就是原因。

我更喜欢强制阻止:

case '1':
{
}

除此之外,这将避免 switch/case 的奇怪变量作用域情况。当然,您仍然可以有多个案例标签:

case '0':
case '1':
{
}

能够更简单地列出多个案例也可能会很好:

case '0', '1':
{
}

哦,对你对现有语言的描述有点挑剔:你不必休息。只是案件的结局必须遥不可及。你也可以有throw,gotoreturn. 可能还有其他我也错过了:)

于 2010-06-24T10:00:14.600 回答
77

从马的口中(MSDN)为什么C# switch 语句设计为不允许掉线,但仍然需要中断?.

引用突出的部分,这就是他们不允许失败的原因:

这种隐含的失败行为通常用于减少所需的代码量,并且在第一次编写代码时通常不是问题。但是,随着代码从初始开发阶段进入维护阶段,上面的代码可能会导致难以调试的细微错误。这些错误是由于开发人员添加一个案例而忘记在块的末尾放置一个非常常见的错误造成的。

在 C# 中,switch 语句要求在 case 结束时进行显式流控制,无论是 break、goto、return 还是 throw。如果开发人员需要贯穿语义,可以通过在 case 语句末尾的显式 goto 来实现。

这就是为什么它不是自动的:

由于 C# 规则要求在 case 块的末尾(最常见的是中断)发生显式流控制,许多人质疑为什么行为根本没有改变,以至于没有发生故障。也就是说,不需要 break ,只需将 switch 的语义更改为没有 case 的 fall-through 即可。没有这样做的原因是,非常习惯于 C++ 的开发人员不会很难理解 switch 语句的作用。

于 2010-06-24T11:29:36.707 回答
52

您可以直接通过,但您必须使用关键字明确地这样做:goto

switch (state) {
    case '1':
        state = '2';
        goto case '2';
    case '2':
        state = '1';
        break;
}

你可以breakgoto在 C# 中,但你不能做的是不说明你想要的,因为这是难以发现的错误的潜在来源。

发现你的代码goto在你想要的时候说break(反之亦然)比发现你忘记添加任何一个要容易得多。

这听起来可能很愚蠢,但是很多人为了寻找 C++ 错误的原因而疲倦了两小时,最终突然意识到您忘记添加 abreak并且您的代码一直在失败。C# 通过强迫你陈述你想要的东西来避免这种情况。

于 2010-06-24T10:12:34.917 回答
12

如果你在案例1中没有任何代码,你可以通过,所以你可以说“所有这些案例都共享这段代码”

于 2010-06-24T09:59:13.743 回答