C# switch语句中的多个case

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/68578/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 11:05:17  来源:igfitidea点击:

Multiple cases in switch statement

提问by theo

Is there a way to fall through multiple case statements without stating case value:repeatedly?

有没有办法在不case value:重复陈述的情况下通过多个 case 语句?

I know this works:

我知道这有效:

switch (value)
{
   case 1:
   case 2:
   case 3:
      // Do some stuff
      break;
   case 4:
   case 5:
   case 6:
      // Do some different stuff
      break;
   default:
       // Default stuff
      break;
}

but I'd like to do something like this:

但我想做这样的事情:

switch (value)
{
   case 1,2,3:
      // Do something
      break;
   case 4,5,6:
      // Do something
      break;
   default:
      // Do the Default
      break;
}

Is this syntax I'm thinking of from a different language, or am I missing something?

这种语法是我从不同的语言中想到的,还是我遗漏了什么?

采纳答案by Brian R. Bondy

There is no syntax in C++ nor C# for the second method you mentioned.

您提到的第二种方法在 C++ 和 C# 中都没有语法。

There's nothing wrong with your first method. If however you have very big ranges, just use a series of if statements.

你的第一种方法没有错。但是,如果您有非常大的范围,只需使用一系列 if 语句。

回答by Neal

This syntax is from the Visual Basic Select...Case Statement:

此语法来自 Visual Basic Select...Case Statement

Dim number As Integer = 8
Select Case number
    Case 1 To 5
        Debug.WriteLine("Between 1 and 5, inclusive")
        ' The following is the only Case clause that evaluates to True.
    Case 6, 7, 8
        Debug.WriteLine("Between 6 and 8, inclusive")
    Case Is < 1
        Debug.WriteLine("Equal to 9 or 10")
    Case Else
        Debug.WriteLine("Not between 1 and 10, inclusive")
End Select

You cannot use this syntax in C#. Instead, you must use the syntax from your first example.

您不能在 C# 中使用此语法。相反,您必须使用第一个示例中的语法。

回答by Cyber Oliveira

One lesser known facet of switchin C# is that it relies on the operator=and since it can be overriden you could have something like this:

C#中switch 的一个鲜为人知的方面是它依赖于operator=并且由于它可以被覆盖,你可以有这样的东西:


string s = foo();

switch (s) {
  case "abc": /*...*/ break;
  case "def": /*...*/ break;
}

回答by DGentry

gcc implements an extension to the C language to support sequential ranges:

gcc 实现了对 C 语言的扩展以支持顺序范围:

switch (value)
{
   case 1...3:
      //Do Something
      break;
   case 4...6:
      //Do Something
      break;
   default:
      //Do the Default
      break;
}

Edit: Just noticed the C# tag on the question, so presumably a gcc answer doesn't help.

编辑:刚刚注意到问题上的 C# 标签,所以大概 gcc 答案没有帮助。

回答by Allan Wind

You can leave out the newline which gives you:

您可以省略换行符,它为您提供:

case 1: case 2: case 3:
   break;

but I consider that bad style.

但我认为这种风格很糟糕。

回答by Dr8k

Another option would be to use a routine. If cases 1-3 all execute the same logic then wrap that logic in a routine and call it for each case. I know this doesn't actually get rid of the case statements, but it does implement good style and keep maintenance to a minimum.....

另一种选择是使用例程。如果案例 1-3 都执行相同的逻辑,则将该逻辑包装在一个例程中并为每个案例调用它。我知道这实际上并没有摆脱 case 语句,但它确实实现了良好的风格并将维护保持在最低限度......

[Edit] Added alternate implementation to match original question...[/Edit]

[编辑] 添加了替代实现以匹配原始问题...[/编辑]

switch (x)
{
   case 1:
      DoSomething();
      break;
   case 2:
      DoSomething();
      break;
   case 3:
      DoSomething();
      break;
   ...
}

private void DoSomething()
{
   ...
}

Alt

替代

switch (x)
{
   case 1:
   case 2:
   case 3:
      DoSomething();
      break;
   ...
}

private void DoSomething()
{
   ...
}

回答by Luca Molteni

.NET Framework 3.5 has got ranges:

.NET Framework 3.5 具有以下范围:

Enumerable.Range from MSDN

Enumerable.Range 来自 MSDN

you can use it with "contains" and the IF statement, since like someone said the SWITCH statement uses the "==" operator.

您可以将它与“包含”和 IF 语句一起使用,因为就像有人说的那样,SWITCH 语句使用“==”运算符。

Here an example:

这里有一个例子:

int c = 2;
if(Enumerable.Range(0,10).Contains(c))
    DoThing();
else if(Enumerable.Range(11,20).Contains(c))
    DoAnotherThing();

But I think we can have more fun: since you won't need the return values and this action doesn't take parameters, you can easily use actions!

但我认为我们可以有更多的乐趣:因为你不需要返回值,而且这个动作不带参数,你可以很容易地使用动作!

public static void MySwitchWithEnumerable(int switchcase, int startNumber, int endNumber, Action action)
{
    if(Enumerable.Range(startNumber, endNumber).Contains(switchcase))
        action();
}

The old example with this new method:

使用这种新方法的旧示例:

MySwitchWithEnumerable(c, 0, 10, DoThing);
MySwitchWithEnumerable(c, 10, 20, DoAnotherThing);

Since you are passing actions, not values, you should omit the parenthesis, it's very important. If you need function with arguments, just change the type of Actionto Action<ParameterType>. If you need return values, use Func<ParameterType, ReturnType>.

由于您传递的是动作,而不是值,因此您应该省略括号,这非常重要。如果您需要带参数的函数,只需将类型更改ActionAction<ParameterType>。如果需要返回值,请使用Func<ParameterType, ReturnType>.

In C# 3.0 there is no easy Partial Applicationto encapsulate the fact the the case parameter is the same, but you create a little helper method (a bit verbose, tho).

在 C# 3.0 中,没有简单的Partial Application来封装 case 参数相同的事实,但是您创建了一个小助手方法(有点冗长,tho)。

public static void MySwitchWithEnumerable(int startNumber, int endNumber, Action action){ 
    MySwitchWithEnumerable(3, startNumber, endNumber, action); 
}

Here an example of how new functional imported statement are IMHO more powerful and elegant than the old imperative one.

这是一个示例,说明新的功能导入语句如何比旧的命令式语句更强大和优雅。

回答by Carlos Quintanilla

I guess this has been already answered. However, I think that you can still mix both options in a syntactically better way by doing:

我想这已经得到了回答。但是,我认为您仍然可以通过执行以下操作以更好的语法方式混合这两个选项:

switch (value)
{
    case 1: case 2: case 3:          
        // Do Something
        break;
    case 4: case 5: case 6: 
        // Do Something
        break;
    default:
        // Do Something
        break;
}

回答by scone

For this, you would use a goto statement. Such as:

为此,您将使用 goto 语句。如:

    switch(value){
    case 1:
        goto case 3;
    case 2:
        goto case 3;
    case 3:
        DoCase123();
    //This would work too, but I'm not sure if it's slower
    case 4:
        goto case 5;
    case 5:
        goto case 6;
    case 6:
        goto case 7;
    case 7:
        DoCase4567();
    }

回答by Ji?í Herník

Actually I don't like the GOTO command too, but it's in official Microsoft materials, and here are all allowed syntaxes.

其实我也不喜欢 GOTO 命令,但它在微软官方资料中,这里是所有允许的语法。

If the end point of the statement list of a switch section is reachable, a compile-time error occurs. This is known as the "no fall through" rule. The example

如果可以到达 switch 部分的语句列表的终点,则会发生编译时错误。这被称为“不落下”规则。这个例子

switch (i) {
case 0:
   CaseZero();
   break;
case 1:
   CaseOne();
   break;
default:
   CaseOthers();
   break;
}

is valid because no switch section has a reachable end point. Unlike C and C++, execution of a switch section is not permitted to "fall through" to the next switch section, and the example

是有效的,因为没有开关部分具有可到达的端点。与 C 和 C++ 不同,一个 switch 部分的执行不允许“落入”到下一个 switch 部分,并且示例

switch (i) {
case 0:
   CaseZero();
case 1:
   CaseZeroOrOne();
default:
   CaseAny();
}

results in a compile-time error. When execution of a switch section is to be followed by execution of another switch section, an explicit goto case or goto default statement must be used:

导致编译时错误。当一个 switch 部分的执行之后是另一个 switch 部分的执行时,必须使用显式的 goto case 或 goto default 语句:

switch (i) {
case 0:
   CaseZero();
   goto case 1;
case 1:
   CaseZeroOrOne();
   goto default;
default:
   CaseAny();
   break;
}

Multiple labels are permitted in a switch-section. The example

一个开关部分中允许有多个标签。这个例子

switch (i) {
case 0:
   CaseZero();
   break;
case 1:
   CaseOne();
   break;
case 2:
default:
   CaseTwo();
   break;
}

I believe in this particular case, the GOTO can be used, and it's actually the only way to fallthrough.

我相信在这种特殊情况下,可以使用 GOTO,它实际上是唯一的方法。

Source: http://msdn.microsoft.com/en-us/library/aa664749%28v=vs.71%29.aspx

来源:http: //msdn.microsoft.com/en-us/library/aa664749%28v=vs.71%29.aspx