switch语句中的多个案例

the*_*heo 552 c# switch-statement

有没有办法在不case value:反复陈述的情况下通过多个案例陈述?

我知道这有效:

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;
}
Run Code Online (Sandbox Code Playgroud)

但是我想做这样的事情:

switch (value)
{
   case 1,2,3:
      //Do Something
      break;
   case 4,5,6:
      //Do Something
      break;
   default:
      //Do the Default
      break;
}
Run Code Online (Sandbox Code Playgroud)

这是我用不同的语言思考的语法,还是我错过了什么?

Car*_*lla 675

我想这已经回答了.但是,我认为您仍然可以通过以下方式在语法上更好地混合两个选项:

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

  • @T_D它得到了支持,因为它实际上回答了这个问题.OP说,我错过了什么......卡洛斯回答了他所遗漏的事情.看起来非常切割和干燥给我.不要讨厌他有422个赞成票. (14认同)
  • 何必?无论如何,Visual Studio 2013中的自动压缩器将恢复为原始问题中的格式. (8认同)
  • @MikeDevenney然后你用不同的方式解释了这个问题,据我所知,正确答案是"不,c#没有任何语法".如果有人问"是否有可能将液体倒入玻璃杯中,我会倒置?" 答案应该是"不"而不是"如果你颠倒地看着它并使用你的想象力,你可以倒出液体",因为这个答案都是关于使用想象力.如果你使用常规语法但是格式化它看起来像其他语法,有一些想象力.希望你明白我的意思......:P (6认同)
  • 对于c#,'switch'应该是小写的? (3认同)
  • @JeremyChild也许是因为这个答案只是一个伪装的问题副本.我投下一个答案的罕见时刻之一.真的,这是如何得到这么多的支持? (3认同)
  • 折叠的代码会延长到问题中的第一个示例.也可以按照它在问题中的方式来做. (2认同)
  • @MikeDevenney例如,我否决了这个答案,因为这与艾伦·温德在两年前给出的答案是相同的!加上一些不必要的绒毛。...哦,我赞成艾伦斯的回答;) (2认同)
  • 我喜欢这个,因为它比把空箱子堆在有东西的箱子上面更好地反映了正在发生的事情。即其中任何一个,做事;而不是可能设置了一堆案例,而程序员错过了在其中一个或多个案例中做某事。这更好地表明了意图。 (2认同)

Bri*_*ndy 303

对于您提到的第二种方法,C++和C#都没有语法.

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

  • 另外,我想在MSDN上添加一个C#语言规范的链接,网址为:http://msdn.microsoft.com/en-us/vcsharp/aa336809.aspx (5认同)
  • 我相信这不再是正确的。请参阅 /sf/ask/1410351561/ 。在这个问题上也有一个答案/sf/answers/3139409381/ (4认同)
  • 可能是从VB.net中选择的 (3认同)

小智 71

此语法来自Visual Basic Select ... Case语句:

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
Run Code Online (Sandbox Code Playgroud)

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

  • 这是我想念*Basic的少数几件事之一. (46认同)
  • 在这里,我们有少数几个显示器,其中visual basic不是那么丑,而且比c#更通用.这是一个有价值的例子! (9认同)
  • 这怎么算是一个答案呢?“您不能使用以下代码” (3认同)

Ste*_*mez 56

原始问题有点晚了,但我发布这个答案是希望有人使用更新的版本(C#7 - 默认情况下在Visual Studio 2017/.NET Framework 4.6.2中可用),会发现它很有帮助.

在C#7中,现在可以使用switch语句进行基于范围的切换,这将有助于解决OP的问题.

例:

int i = 5;

switch (i)
{
    case int n when (n >= 7):
        Console.WriteLine($"I am 7 or above: {n}");
        break;

    case int n when (n >= 4 && n <= 6 ):
        Console.WriteLine($"I am between 4 and 6: {n}");
        break;

    case int n when (n <= 3):
        Console.WriteLine($"I am 3 or less: {n}");
        break;
}

// Output: I am between 4 and 6: 5
Run Code Online (Sandbox Code Playgroud)

笔记:

  • 括号(并且)when条件中不是必需的,但在本示例中用于突出显示比较.
  • var也可以用来代替int.例如:case var n when n >= 7:.

  • 当您可以使用C#7.x或更高版本时,这种(模式匹配)通常应该是最佳实践,因为它比其他答案更清晰. (3认同)

All*_*ind 32

你可以省略换行符给你:

case 1: case 2: case 3:
   break;
Run Code Online (Sandbox Code Playgroud)

但我认为那种糟糕的风格.


Luc*_*eni 18

.NET Framework 3.5有范围:

来自MSDN的Enumerable.Range

您可以将它与"contains"和IF语句一起使用,因为有人说SWITCH语句使用"=="运算符.

这是一个例子:

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

但我认为我们可以获得更多乐趣:因为您不需要返回值而且此操作不带参数,您可以轻松使用操作!

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

这个新方法的旧例子:

MySwitchWithEnumerable(c, 0, 10, DoThing);
MySwitchWithEnumerable(c, 10, 20, DoAnotherThing);
Run Code Online (Sandbox Code Playgroud)

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

在C#3.0中没有简单的部分应用程序来封装case参数相同的事实,但你创建了一个小帮助方法(有点冗长,tho).

public static void MySwitchWithEnumerable(int startNumber, int endNumber, Action action){ 
    MySwitchWithEnumerable(3, startNumber, endNumber, action); 
}
Run Code Online (Sandbox Code Playgroud)

这里有一个新功能导入语句如何比旧命令更强大和优雅的例子.

  • 好的选择.有一点需要注意,但是 - Enumerable.Range有参数`int start`和`int count`.你的例子不会按照它们的编写方式工作.你写它好像第二个参数是`int end`.例如 - "Enumerable.Range(11,20)`将导致从11开始的20个数字,而不是从11到20的数字. (3认同)
  • 注意`Enumerable.Range(11,20).Contains(c)`相当于`for(int i = 11; i <21; ++ i){if(i == c)return true; } return false;`如果你有一个很大的范围,它需要很长时间,而只需使用`>`和`<`将是快速和恒定的时间. (3认同)

Car*_*lin 11

这是完整的C#7解决方案...

switch (value)
{
   case var s when new[] { 1,2,3 }.Contains(s):
      //Do Something
      break;
   case var s when new[] { 4,5,6 }.Contains(s):
      //Do Something
      break;
   default:
      //Do the Default
      break;
}
Run Code Online (Sandbox Code Playgroud)

也可以使用字符串...

switch (mystring)
{
   case var s when new[] { "Alpha","Beta","Gamma" }.Contains(s):
      //Do Something
      break;
...
}
Run Code Online (Sandbox Code Playgroud)

  • 这意味着您使用每个 switch 语句分配数组,对吗?如果我们将它们作为常量变量不是更好吗? (2认同)
  • 很优雅,但如果知道编译器是否优化了这种情况确实很好,这样重复调用就不会每次都产生数组构造的开销;提前定义数组是一种选择,但会失去很多优雅性。 (2认同)

Ess*_*set 9

C#9 带来了关系模式匹配。这使我们能够做到:

switch (value)
{
    case 1 or 2 or 3:
      // Do stuff
      break;
    case 4 or 5 or 6:
      // Do stuff
      break;
    default:
        // Do stuff
        break;
}
Run Code Online (Sandbox Code Playgroud)

在 C#9 中的关系模式的深入教程中

C# 9.0 的模式匹配更改

关系模式允许程序员表达与常量值相比,输入值必须满足关系约束


Mis*_*sky 9

在 C# 8.0 中,您可以使用新的switch 表达式语法,它非常适合您的情况。

var someOutput = value switch
{
    >= 1 and <= 3 => <Do some stuff>,
    >= 4 and <= 6 => <Do some different stuff>,
    _ => <Default stuff>
};
Run Code Online (Sandbox Code Playgroud)


小智 8

@ Jennifer Owens:你绝对正确,下面的代码不起作用:

case 1 | 3 | 5:
//not working do something
Run Code Online (Sandbox Code Playgroud)

唯一的方法是:

case 1: case 2: case 3:
// do something
break;
Run Code Online (Sandbox Code Playgroud)

你正在寻找的代码适用于visual basic,你可以很容易地放置范围...在没有选项的开关或if else块方便,我建议,在非常极端的点,使用visual basic和导入返回.dll到你的c#项目.

注意:visual basic中的等效开关是select case.


Dr8*_*r8k 7

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

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

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

private void DoSomething()
{
   ...
}
Run Code Online (Sandbox Code Playgroud)

Alt键

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

private void DoSomething()
{
   ...
}
Run Code Online (Sandbox Code Playgroud)


Luk*_*ien 6

在 C# 7 中,我们现在有模式匹配,因此您可以执行以下操作:

switch (age)
{
  case 50:
    ageBlock = "the big five-oh";
    break;
  case var testAge when (new List<int>()
      { 80, 81, 82, 83, 84, 85, 86, 87, 88, 89 }).Contains(testAge):
    ageBlock = "octogenarian";
    break;
  case var testAge when ((testAge >= 90) & (testAge <= 99)):
    ageBlock = "nonagenarian";
    break;
  case var testAge when (testAge >= 100):
    ageBlock = "centenarian";
    break;
  default:
    ageBlock = "just old";
    break;
}
Run Code Online (Sandbox Code Playgroud)


Cyb*_*ira 5

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


string s = foo();

switch (s) {
  case "abc": /*...*/ break;
  case "def": /*...*/ break;
}
Run Code Online (Sandbox Code Playgroud)

  • 对于其他试图阅读代码的人来说,这可能会成为一个大问题 (4认同)

DGe*_*try 5

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

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

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


Vik*_*ani 5

我认为这个在 C# 7 或更高版本中更好。

switch (value)
{
    case var s when new[] { 1,2 }.Contains(s):
    // Do something
     break;
   
    default:
    // Do the default
    break;
 }
Run Code Online (Sandbox Code Playgroud)

您还可以在 C# switch case 中检查 Range:Switch case: can I use a rangerather not a one number

或者

 int i = 3;

        switch (i)
        {
            case int n when (n >= 7):
                Console.WriteLine($"I am 7 or above: {n}");
                break;

            case int n when (n >= 4 && n <= 6):
                Console.WriteLine($"I am between 4 and 6: {n}");
                break;

            case int n when (n <= 3):
                Console.WriteLine($"I am 3 or less: {n}");
                break;
        }
Run Code Online (Sandbox Code Playgroud)

C# 中切换大小写多个条件

或者如果您想了解 C# switch case的基础知识


pin*_*ing 5

C# 8 方法:

var value = 5;
var output = value switch
{
    1 or 2 or 3 => value + 4,// Do some stuff
    4 => value * 3,// Do some different stuff
    5 => value / 3,// Do some different stuff
    6 => value - 3,// Do some different stuff
    _ => value  // Default stuff
};
Run Code Online (Sandbox Code Playgroud)