C# 中的 Switch 语句失败?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/174155/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Switch statement fallthrough in C#?
提问by Matthew Scharley
Switch statement fallthrough is one of my personal major reasons for loving switch
vs. if/else if
constructs. An example is in order here:
Switch 语句失败是我个人喜欢switch
vs.if/else if
结构的主要原因之一。这里有一个例子:
static string NumberToWords(int number)
{
string[] numbers = new string[]
{ "", "one", "two", "three", "four", "five",
"six", "seven", "eight", "nine" };
string[] tens = new string[]
{ "", "", "twenty", "thirty", "forty", "fifty",
"sixty", "seventy", "eighty", "ninety" };
string[] teens = new string[]
{ "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen",
"sixteen", "seventeen", "eighteen", "nineteen" };
string ans = "";
switch (number.ToString().Length)
{
case 3:
ans += string.Format("{0} hundred and ", numbers[number / 100]);
case 2:
int t = (number / 10) % 10;
if (t == 1)
{
ans += teens[number % 10];
break;
}
else if (t > 1)
ans += string.Format("{0}-", tens[t]);
case 1:
int o = number % 10;
ans += numbers[o];
break;
default:
throw new ArgumentException("number");
}
return ans;
}
The smart people are cringing because the string[]
s should be declared outside the function: well, they are, this is just an example.
聪明的人害怕,因为string[]
s 应该在函数之外声明:嗯,他们是,这只是一个例子。
The compiler fails with the following error:
编译器失败并出现以下错误:
Control cannot fall through from one case label ('case 3:') to another Control cannot fall through from one case label ('case 2:') to another
Why? And is there any way to get this sort of behaviour without having three if
s?
为什么?有没有办法在没有三个if
s 的情况下获得这种行为?
采纳答案by Alex Lyman
(Copy/paste of an answer I provided elsewhere)
Falling through switch
-case
s can be achieved by having no code in a case
(see case 0
), or using the special goto case
(see case 1
) or goto default
(see case 2
) forms:
通过下降switch
- case
S可通过不具有代码在一个来实现case
(见case 0
),或者使用特殊的goto case
(见case 1
)或goto default
(见case 2
)形式:
switch (/*...*/) {
case 0: // shares the exact same code as case 1
case 1:
// do something
goto case 2;
case 2:
// do something else
goto default;
default:
// do something entirely different
break;
}
回答by Ken
They changed the switch statement (from C/Java/C++) behavior for c#. I guess the reasoning was that people forgot about the fall through and errors were caused. One book I read said to use goto to simulate, but this doesn't sound like a good solution to me.
他们更改了 c# 的 switch 语句(来自 C/Java/C++)行为。我想原因是人们忘记了失败并导致了错误。我读过的一本书说使用 goto 进行模拟,但这对我来说听起来不是一个好的解决方案。
回答by Powerlord
A jump statement such as a break is required after each case block, including the last block whether it is a case statement or a default statement. With one exception, (unlike the C++ switch statement), C# does not support an implicit fall through from one case label to another. The one exception is if a case statement has no code.
每个 case 块之后都需要一个跳转语句,例如 break,包括最后一个块,无论它是 case 语句还是 default 语句。除了一个例外(与 C++ switch 语句不同),C# 不支持从一个 case 标签到另一个 case 标签的隐式失败。一个例外是 case 语句没有代码。
回答by BFree
回答by Biri
They left out this behaviour by design to avoid when it was not used by will but caused problems.
他们在设计上忽略了这种行为,以避免它不是由意志使用而是引起问题的。
It can be used only if there is no statement in the case part, like:
只有在 case 部分没有声明时才能使用它,例如:
switch (whatever)
{
case 1:
case 2:
case 3: boo; break;
}
回答by Coincoin
Switch fallthrough is historically one of the major source of bugs in modern softwares. The language designer decided to make it mandatory to jump at the end of the case, unless you are defaulting to the next case directly without processing.
切换失败历来是现代软件中错误的主要来源之一。语言设计者决定强制在案例结束时跳转,除非您默认直接跳转到下一个案例而不进行处理。
switch(value)
{
case 1:// this is still legal
case 2:
}
回答by kenny
You can 'goto case label' http://www.blackwasp.co.uk/CSharpGoto.aspx
您可以“转到案例标签” http://www.blackwasp.co.uk/CSharpGoto.aspx
The goto statement is a simple command that unconditionally transfers the control of the program to another statement. The command is often criticised with some developers advocating its removal from all high-level programming languages because it can lead to spaghetti code. This occurs when there are so many goto statements or similar jump statements that the code becomes difficult to read and maintain. However, there are programmers who point out that the goto statement, when used carefully, provides an elegant solution to some problems...
goto 语句是一个简单的命令,它无条件地将程序的控制权转移到另一个语句。该命令经常受到批评,一些开发人员主张将其从所有高级编程语言中删除,因为它可能导致意大利面条式代码。当有太多的 goto 语句或类似的跳转语句导致代码变得难以阅读和维护时,就会发生这种情况。但是,也有程序员指出 goto 语句,如果谨慎使用,可以为一些问题提供优雅的解决方案......
回答by Marcus
You forgot to add the "break;" statement into case 3. In case 2 you wrote it into the if block. Therefore try this:
你忘了加上“break;” 语句进入案例 3。在案例 2 中,您将其写入 if 块。因此试试这个:
case 3:
{
ans += string.Format("{0} hundred and ", numbers[number / 100]);
break;
}
case 2:
{
int t = (number / 10) % 10;
if (t == 1)
{
ans += teens[number % 10];
}
else if (t > 1)
{
ans += string.Format("{0}-", tens[t]);
}
break;
}
case 1:
{
int o = number % 10;
ans += numbers[o];
break;
}
default:
{
throw new ArgumentException("number");
}
回答by Jon Skeet
The "why" is to avoid accidental fall-through, for which I'm grateful. This is a not uncommon source of bugs in C and Java.
“为什么”是为了避免意外跌倒,对此我很感激。这是 C 和 Java 中错误的常见来源。
The workaround is to use goto, e.g.
解决方法是使用 goto,例如
switch (number.ToString().Length)
{
case 3:
ans += string.Format("{0} hundred and ", numbers[number / 100]);
goto case 2;
case 2:
// Etc
}
The general design of switch/case is a little bit unfortunate in my view. It stuck too close to C - there are some useful changes which could be made in terms of scoping etc. Arguably a smarter switch which could do pattern matching etc would be helpful, but that's really changing from switch to "check a sequence of conditions" - at which point a different name would perhaps be called for.
开关/外壳的总体设计在我看来有点不幸。它离 C 太近了 - 可以在范围等方面进行一些有用的更改。可以说,可以进行模式匹配等的更智能的开关会有所帮助,但这确实从开关变为“检查条件序列” - 那时可能需要一个不同的名字。
回答by Shilpa gulati
After each case statement require breakor gotostatement even if it is a default case.
在每个 case 语句之后都需要break或goto语句,即使它是默认情况。