How can I use more than one constant for a switch case in C#?
如何使用一个以上的常数作为开关箱C?从概念上讲,我在寻找这样的东西:
1 2 3 4 5 6
| switch(n)
{
case 1,2,3: //????
case 4:
default:
} |
- C中可能重复的switch语句fallthrough?
- stackoverflow.com/questions/174155/…副本
许多答案表明,"如果案件是空的,破产是合法的"。
这是不正确的。这是错误的思考方式。这是一种推理,就好像C是C,而不是C。在C中,每个case标签都有一个关联的语句列表,可能是空的,并且控件"falls through"在语句列表的末尾。C中没有这种情况。
在C中,开关由多个部分组成,每个部分有一个或多个大小写标签,每个部分有一个或多个语句。当你说
1 2 3 4 5 6 7
| switch(x)
{
case 1:
case 2:
M();
break;
} |
不是有两个开关段的情况,一个用于案例1,一个用于案例2,案例1的开关段为空,落入第二个块。这就是C中的情况,但C不是C。
在C中,本例中有一个开关部分。它有两个标签和一个语句列表。大小写标签之间没有空的语句列表;不能有,因为语句列表位于节中最后一个标签之后。让我重复一遍:这里没有一个空的语句列表。根本没有语句列表,甚至没有空的语句列表。
这一特征使我们能够清楚地说明C中的"失败总是非法的",句号。同样,控制"通过"不是从案例1的空语句列表进入案例2的情况。控制永远不会失败。控件不会通过这里,因为控件从未在案例1之后进入空语句列表。控件无法进入该空语句列表,因为首先没有空语句列表。语句列表在案例2之后才开始。
c在每个开关部分(包括最后一个)强制执行"禁止坠落"规则。这样就可以任意地重新排序开关部分,可能是通过机械工具,而不会在程序中引入语义更改。
C通过要求每个开关段的终点不可到达来强制执行不通过规则。开关段不必以中断结束。它可以以中断、返回、转到、继续、抛出或可检测的无限循环结束:
1 2 3 4 5 6 7 8 9 10 11 12
| switch(x )
{
case 1:
while(true) M ();
case 2:
return 123;
case 3:
throw new Exception ();
case 4:
M ();
goto case 3;
} |
以上都是合法的,没有休息。
- 我最初的印象是,这是学究式的,因为说,"c不支持fall through,但允许多个case语句"和"c支持fall through only with empty case语句"乍一看是等效的。但是,"C支持只通过空case语句"意味着空case语句是合法的,这是不正确的(显然,如果您对最后一个case语句使用空case语句)。我想,当你这样做时,C有一个错误的事实("EDOCX1〔0])暗示了这一点。
- 这很学究,但不仅仅是学究。
- 谢谢你的解释。
- 你已经向我解释了为什么这方面的建议总是矛盾的。谢谢你@ericlippert!
1 2 3 4 5 6 7 8 9 10
| switch(n)
{
case 1:
case 2:
case 3:
// do something
break;
default:
break;
} |
最接近C中贯穿开关箱的东西:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| switch(n)
{
case 1:
// Do something
goto case 2;
case 2:
// Do something
goto case 3;
case 3:
// Do something
break;
default:
break;
} |
有关详细信息,请参阅此处:
http://msdn.microsoft.com/en-us/vcsharp/aa336815.aspx
- +1因为在这种情况下,它更像一个经典的故障转移(而不是没有模块的情况)。
你不,你用的是摔倒。
1 2 3 4 5 6 7 8 9 10
| switch( n )
{
case x:
case y:
case z:
DoSomething( );
break;
case blah:
break;
} |
- 如果箱身为空,允许坠落。
- 是的,是的。只要最后一个案例中没有任何代码,您就可以失败。
- 啊!我接受纠正。
- 另外,仅供参考,如果您希望代码在主体中,并且希望它能够通过,那么您必须使用goto语句,但我建议不要触摸这些语句。
- @迈赫达德:把C当成C的推理是错误的思考方式。正确的方法是:(1)一个开关段可能有一个或多个开关标签,(2)每个开关段的终点必须是不可到达的。当你说"案例1:案例2:…"时,并不是说在案例1和案例2之间有一个空的切换部分。那里根本没有任何开关部分,不管是空的还是不空的。在案例完成之前,切换部分甚至不会开始。
- @艾德:这是不合法的。您不能有任何空的开关盒体,即使是最后一个。每个开关段的终点必须是不可到达的。
- @埃里克:谢谢你的澄清!事实上,我的评论是对一条(现在已删除的)评论的回应,该评论说"C_中不允许通过"。
- @Mehrdad一定很喜欢删除的评论,这让你看起来有点疯狂。;)
- -1当作为示例提供的代码有编译器错误时,声明您使用的是fall-through:Error: Control cannot fall through from one case label ('case blah:') to another。
- 是的,是的。会解决这个问题的,尽管它确实与回答的问题无关。
- 我一直在抱怨术语:前一版本代码的编译器错误明确地表示c case标签不使用fall-through,所以您的术语是错误的……而且非常明显,因为它意味着前一个代码是正确的,而不是正确的。有关术语问题的讨论,请参阅Eric Lippert的答案。
- 好啊。。。你可以这样称呼它,但在这个例子中,你肯定是在"经历"案例x和y。因此,更准确地说,如果case语句体中有任何代码,则不允许出现故障。
- 所以这个公认的答案是错误的?
- @Jennyo'Reilly:这里的辩论围绕着"失败"一词的使用展开。实际上,对于我们这些不设计编译器的人来说,这是无关紧要的。但是,埃里克·利珀特显然知道他在说什么,所以如果你对细节感兴趣,我建议你读一下他的答案。
- 我对这个答案的问题是,无论谁读到它,都会对它的工作方式产生错误的看法,并将其传递给其他人。虽然最终功能是相同的,但对它的解释仍然是错误的。
- @Jennyo'Reilly:请向我解释它的错误之处,以及它将如何影响某人对解决方案的实际应用。
- 这个解释是错误的,因为没有摔倒,也没有空箱子。为一个案例指定了多个标签。语法使它看起来像一个失败,但正如埃里克·利珀特指出的,它不是如何工作的。它将如何影响应用程序?一点也不。但有人可能会认为,如果这是一个下降槽,可以向"case x"添加语句,它仍然会以同样的方式工作。对我来说,这已经解决了。如果你还是不按我的方式看,我就无法"说服"你。祝你今天愉快。-)
- @詹尼奥·赖利:那么,你对我的问题的回答是"不"。你在重复我们六年前在这里进行的语义辩论。是的,它在技术上是正确的描述。埃里克·利珀特自己解释了这一点,我希望他能如此严格,因为作为一名语言律师是他的工作。然而,绝大多数人并不知道这是事实,事实上,它只是混淆了,因为C直接模仿了C的语法。语义学是很好知道的,没有什么错,但是它们在实践中完全没有改变。
- @詹尼奥·赖利:这里没有什么可以"说服我"的。我理解我的措辞在技术上是不正确的,但是这个对话完全是学术性的,因为它与问题(或者在实现C编译器之外的任何问题)没有关系。
- 这就像是说太阳在上下运动,而实际上地球在绕太阳运动。对于一个只关心地球上是什么样子的人来说,这两件事是完全相同的。如果你对它的实际工作方式感兴趣,它们是完全不同的。只有你用你的(错误的)知识来进一步发展,这才可能重要。那你可能会迷惑不解。
- @Jennyo'Reilly:除了这个类比是错误的,因为如果没有一个正确的天体在太空中运动的模型,人们就不能在未来做出准确的预测。换言之,犯错有一个实际的、可察觉的后果。所以,如果你认为你的类比是正确的,给我看一个(只有一个!)语义定义与实际代码不同的实例。我还在等这个呢,顺便说一句,如果你想掩饰你的学究气,好像它有一些有用的目的,你至少得弥补点什么。
- 我认为我已经回答了你的问题,并给出了一个例子:"它将如何影响一个应用程序?一点也不。但人们可能会认为,如果这是一个下降槽,你可以在"案例X"中添加语句,它仍然会以同样的方式工作。"我的意思是,如果认为它是通过下降来工作的,你可能会对如何使用案例语句得出错误的结论,然后想知道为什么某些事情不能工作。如果我不能把这个说清楚,我很抱歉。
- "我的意思是,如果认为它是通过失败而起作用的话,你可能会对如何使用案例陈述得出错误的结论,然后想知道为什么某些事情不起作用"—好吧,这将是一个现实世界的问题,对吧?给我举个例子。
试试这个:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| switch(n)
{
case 1:
case 2:
case 3:
//Do Stuff
break;
case 4:
//Do more stuff
break;
default:
//Do standard stuff
break;
} |
请记住,只有在case 1:或case 2:块中没有代码时,这才有效。i
- 正如我上面提到的,这是错误的思考方式。案例1没有空块。完全没有块,这与空块不同!第一个开关段块直到案例3之后才开始。
你可以这样做:
1 2 3 4 5 6 7 8 9
| switch(n)
{
case 1: case 2: case 3:
break;
case 4:
break;
default:
break;
} |