是否有一种方法可以通过多个case语句而不声明case值:重复?

我知道这很管用:

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;
}

但我想这样做:

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

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


当前回答

为了让c#中最不常用的语法之一看起来更好或工作得更好,似乎已经做了大量的工作。我个人认为switch语句很少值得使用。我强烈建议你分析你正在测试的数据和你想要的最终结果。

让我们举个例子,你想快速测试一个已知范围内的值,看看它们是否是质数。你想要避免让你的代码做浪费的计算,你可以在网上找到你想要的范围内的质数列表。您可以使用一个大型switch语句将每个值与已知素数进行比较。

或者你可以创建一个质数的数组映射,并立即得到结果:

    bool[] Primes = new bool[] {
        false, false, true, true, false, true, false,    
        true, false, false, false, true, false, true,
        false,false,false,true,false,true,false};
    private void button1_Click(object sender, EventArgs e) {
        int Value = Convert.ToInt32(textBox1.Text);
        if ((Value >= 0) && (Value < Primes.Length)) {
            bool IsPrime = Primes[Value];
            textBox2.Text = IsPrime.ToString();
        }
    }

也许你想看看字符串中的一个字符是否是十六进制的。您可以使用一个ungly和有点大的switch语句。

或者你可以使用正则表达式来测试字符,或者使用IndexOf函数在已知的十六进制字母字符串中搜索字符:

        private void textBox2_TextChanged(object sender, EventArgs e) {
        try {
            textBox1.Text = ("0123456789ABCDEFGabcdefg".IndexOf(textBox2.Text[0]) >= 0).ToString();
        } catch {
        }
    }

Let us say you want to do one of 3 different actions depending on a value that will be the range of 1 to 24. I would suggest using a set of IF statements. And if that became too complex (Or the numbers were larger such as 5 different actions depending on a value in the range of 1 to 90) then use an enum to define the actions and create an array map of the enums. The value would then be used to index into the array map and get the enum of the action you want. Then use either a small set of IF statements or a very simple switch statement to process the resulting enum value.

此外,将一系列值转换为操作的数组映射的好处是可以通过代码轻松更改它。使用硬连线代码,你不能轻易地在运行时改变行为,但使用数组映射则很容易。

其他回答

.NET Framework 3.5有如下的范围:

可列举的。范围从MSDN

你可以将它与“contains”和IF语句一起使用,因为有人说SWITCH语句使用“==”操作符。

这里有一个例子:

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

但是我认为我们可以有更多的乐趣:因为您不需要返回值,而且这个操作不接受参数,所以您可以轻松地使用操作!

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

这个新方法的旧示例:

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

因为你传递的是动作,而不是值,所以你应该省略圆括号,这很重要。如果需要带参数的函数,只需将Action的类型更改为Action<ParameterType>。如果需要返回值,请使用Func<ParameterType, ReturnType>。

在c# 3.0中,没有简单的局部应用程序来封装case参数相同的事实,但您可以创建一个小的辅助方法(虽然有点啰嗦)。

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

这里有一个例子,说明新的函数导入语句如何比旧的命令式语句更强大和优雅。

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

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

你也可以在c#的开关情况下检查范围:开关情况:我可以使用一个范围而不是一个数字

OR

 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;
        }

在c#中切换多个情况

或者如果你想了解基础知识 c#开关箱

在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;
}

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

[编辑]增加了匹配原始问题的替代实现…[/编辑]

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()
{
   ...
}

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

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

编辑:刚刚注意到这个问题上有c#标签,所以gcc的答案可能没有帮助。