切换大小写:我可以使用范围而不是一个数字吗


86

我想使用开关,但是我有很多情况,有没有捷径?到目前为止,我知道并尝试过的唯一解决方案是:

switch (number)
{
case 1: something; break;
case 2: other thing; break;
...
case 9: .........; break;
}

我希望我能做的是:

switch (number)
{
case (1 to 4): do the same for all of them; break;
case (5 to 9): again, same thing for these numbers; break;
}

1
您可以在这种情况下使用if-else
2013年

Answers:


226

这个问题在游戏中有些晚了,但是在C#7中引入的最新更改(默认在Visual Studio 2017 / .NET Framework 4.6.2中可用),现在可以使用该switch语句进行基于范围的切换。

例:

int i = 63;

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

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

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

笔记:

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

10
先生,您是我的英雄。我想用一些脏话来强调这一点,但不是。:)
Gawie Greef

2
()周围的when条件是不必要的。即case int n when n >= 100:也可以。
Uwe Keim '18年

6
甚至var有效:即case var n when n >= 100:
Uwe Keim

9
@JamesKo我认为,与一堆if语句相比,它是干净的并提高了可读性,尤其是当您具有3-4个以上的条件时。
萨克

1
远远优于一堆if语句,它要干净得多。
约翰·

44

对于您的问题陈述,这是一个更好而优雅的解决方案。

int mynumbercheck = 1000;
// Your number to be checked
var myswitch = new Dictionary <Func<int,bool>, Action>
            { 
             { x => x < 10 ,    () => //Do this!...  },  
             { x => x < 100 ,    () => //Do this!...  },
             { x => x < 1000 ,    () => //Do this!...  },
             { x => x < 10000 ,   () => //Do this!... } ,
             { x => x < 100000 ,  () => //Do this!... },
             { x => x < 1000000 ,  () => //Do this!... } 
            };

现在打电话给我们的条件开关

   myswitch.First(sw => sw.Key(mynumbercheck)).Value();

替代开关/ ifElse


1
@Akxaya我仍然认为switch应该在C#中扩展,但这看起来很棒,并且看起来工作得很好。非常感谢您分享此示例。谢谢
WonderWorker

这不是开关/案例问题范围的明确答案。
指针为空,

13
字典不按添加顺序存储和返回值。这恰好适用于Microsoft编译器,但是可以在不起作用的地方轻松编写兼容的编译器。而是使用List <KeyValuePair <Func <int,bool>,Action >>。另请注意,生成数据结构会产生成本,因此它可能应该是静态只读成员。
内森·菲利普斯

@PointerNull:请在博客中阅读注释中编写的所需代码,以备将来参考
Akxaya

@NathanPhillips:感谢您提出来。当然,IList集合也可以替代。这只是我使用List <t>使用复杂参数实现的示例。
Akxaya

13

我将使用三元运算符对您的切换条件进行分类。

所以...

switch( number > 9 ? "High" :
        number > 5 ? "Mid" :
        number > 1 ? "Low" : "Floor")
        {
              case "High":
                    do the thing;
                    break;
               case "Mid":
                    do the other thing;
                    break;
               case "Low":
                    do something else;
                    break;
               case "Floor":
                    do whatever;
                    break;
         }

12

为了完成线程,这是C#8的语法:

  var percent = price switch
  {
    var n when n >= 1000000 => 7f,
    var n when n >= 900000 => 7.1f,
    var n when n >= 800000 => 7.2f,
    _ => 0f // default value
  };

如果要指定范围:

  var percent2 = price switch
  {
    var n when n >= 1000000 => 7f,
    var n when n < 1000000 && n >= 900000 => 7.1f,
    var n when n < 900000 && n >= 800000 => 7.2f,
    _ => 0f // default value
  };

8

在这种情况下应该使用if-else,但是如果出于任何原因仍然需要切换,则可以执行以下操作,不中断的第一种情况将传播到遇到第一个中断为止。如先前的答案所建议,我建议if-else切换。

switch (number){
            case 1:
            case 2:
            case 3:
            case 4: //do something;
                    break;
            case 5:
            case 6:
            case 7:
            case 8:
            case 9: //Do some other-thing;
                   break;
        }

8

switch通过结合使用List您的界限,可以构造“手柄”范围。

List<int> bounds = new List<int>() {int.MinValue, 0, 4, 9, 17, 20, int.MaxValue };

switch (bounds.IndexOf(bounds.Last(x => x < j)))
{
    case 0: // <=0
        break;

    case 1: // >= 1 and <=4
        break;
    case 2: // >= 5 and <=9
        break;
    case 3: // >= 10 and <=17
        break;
    case 4: // >= 18 and <=20
        break;

    case 5: // >20
        break;
}

使用这种方法,范围可以具有不同的跨度。


6

间隔是恒定的:

 int range = 5
 int newNumber = number / range;
 switch (newNumber)
 {
      case (0): //number 0 to 4
                break;
      case (1): //number 5 to 9
                break;
      case (2): //number 10 to 14
                break;
      default:  break;
 }

除此以外:

  if else

3

如前所述,if-else在这种情况下,您将要处理一个范围会更好:

if(number >= 1 && number <= 4)
{
   //do something;
}
else if(number >= 5 && number <= 9)
{
   //do something else;
}

2

在.Net中,只有Visual Basic允许在switch语句中使用范围,但是在C#中,对此没有有效的语法。

解决C#中的特定问题,我将通过以下方式解决:

if(number >= 1 && number <= 9) // Guard statement
{
    if(number < 5)
    {
        // Case (1 to 4):

        //break;

    }
    else
    {
        // Case (5 to 9):

        //break;

    }

}
else
{
    // Default code goes here

    //break;

}

为了进一步说明这一点,假设您有一个百分比值。

使用您的问题作为模板,您可能希望它看起来像:

switch (percentage)
{
    case (0 to 19):
        break;

    case (20 to 39):
        break;

    case (40 to 69):
        break;

    case (70 to 79):
        break;

    case (80 to 100):
        break;

    default:
        break;

}

但是,由于C#不允许使用该语法,因此以下是C#允许的解决方案:

if (percentage >= 0 && percentage <= 100) // Guard statement
{
    if (percentage >= 40)
    {
        if (percentage >= 80)
        {
            // Case (80% to 100%)

            //break;

        }
        else
        {
            if (percentage >= 70)
            {
                // Case (70% to 79%)

                //break;

            }
            else
            {
                // Case (40% to 69%)

                //break;

            }

        }

    }
    else
    {
        if (percentage >= 20)
        {
            // Case (20% to 39%)

            //break;

        }
        else
        {
            // Case (0% to 19%)

            //break;

        }

    }

}
else
{
    // Default code goes here

    //break;

}

这可能需要一点时间来适应,但是一旦您习惯了就可以了。

就个人而言,我欢迎使用switch语句允许范围。

C#switch语句的未来

这是我对如何改进switch语句的一些想法:

版本A

switch(value)
{
    case (x => x >= 1 && x <= 4):
    break;

    case (x => x >= 5 && x <= 9):
    break;

    default:
    break;

}

版本B

switch(param1, param2, ...)
{
    case (param1 >= 1 && param1 <= 4):
    break;

    case (param1 >= 5 && param1 <= 9 || param2 != param1):
    break;

    default:
    break;

}

1

如果使用C / C ++,则没有“范围”语法。您只能在每个“案例”细分之后列出所有值。语言Ada或Pascal支持范围语法。


0

首先,您应指定要使用的编程语言。其次,switch语句适合用于与开关变量有关的封闭式选项集,例如枚举或预定义字符串。对于这种情况,我建议使用良好的旧if-else结构。


0

通过switch案例是不可能的。您可以使用嵌套的if语句。

if(number>=1 && number<=4){
//Do something
}else if(number>=5 && number<=9){
//Do something
}

那好老(number >= 1 && number <= 4)而不是检查每个数字呢?您如何在1到120之间书写?;-)
DarkDust

哦,要注意=对比==
DarkDust

-1

如果问题是关于C的(您没有说),那么答案是否定的,但是:GCC和Clang(也许还有其他)支持范围语法,但这不是有效的ISO C:

switch (number) {
    case 1 ... 4:
        // Do something.
        break;

    case 5 ... 9:
        // Do something else.
        break;
}

请确保在之前或之后有一个空格,...否则您将收到语法错误。


Pascal / delphi也这样做。案例编号1..4:做点什么;等
Kell 2014年

现在的问题是关于C#

@SuB:我知道。在OP最终告诉我们该问题涉及哪种语言之后,我在此问题上添加了C#标记。但是对于那些通过搜索引擎来到这里的人来说,答案可能仍然有用,这就是为什么我没有删除它。
DarkDust

-1

在C#转换案例中,基本上是下一步该怎么做的字典。由于您无法在字典中查找范围,因此,您最好的情况是……当陈述史蒂夫·戈麦斯(Steve Gomez)提到时。


-3

您可以将| if-else语句与||一起使用 运算子(or-operator),例如:

if(case1 == true || case2 == true || case3 == true)
   {
    Do this!... 
   }
else if(case4 == true || case5 == true || case6 == true)
   {
    Do this!... 
   }
else if(case7 == true || case8 == true || case9 == true)
   {
    Do this!... 
   }

哇,这有点复杂if (number >= 1 && number <= 4) { … } else if (number >= 5 && number <= 9) { … },你不觉得吗?
DarkDust

哦,是的。。嗯,但是如果本来应该做同样事情的案件没有命令,则需要使用'||。运营商...”
Lukas Warsitz

但他的意思是要检查数字是否在范围内,因此顺序无关紧要(检查的范围除外)。
DarkDust

这不是故障,您的解决方案没有错,只是复杂;-)
DarkDust

== true:face_palm:这是默认行为,对于== false,您可以使用not运算符
Et7f3XIV
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.