Switch case: can I use a range instead of a one number

C#Switch Statement

C# Problem Overview


I want to use switch, but I have many cases, is there any shortcut? So far the only solution I know and tried is:

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

What I hope I'm able to do is something like:

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

C# Solutions


Solution 1 - C#

Original Answer for C# 7

A bit late to the game for this question, but in recent changes introduced in C# 7 (Available by default in Visual Studio 2017/.NET Framework 4.6.2), range-based switching is now possible with the switch statement.

Example:

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

Notes:

  • The parentheses ( and ) are not required in the when condition, but are used in this example to highlight the comparison(s).
  • var may also be used in lieu of int. For example: case var n when n >= 100:.

Updated examples for C# 9

switch(myValue)
{
    case <= 0:
        Console.WriteLine("Less than or equal to 0");
        break;
    case > 0 and <= 10:
        Console.WriteLine("More than 0 but less than or equal to 10");
        break;
    default:
        Console.WriteLine("More than 10");
        break;
}

or

var message = myValue switch
{
    <= 0 => "Less than or equal to 0",
    > 0 and <= 10 => "More than 0 but less than or equal to 10",
    _ => "More than 10"
};
Console.WriteLine(message);

Solution 2 - C#

Here is a better and elegant solution for your problem statement.

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

Now to call our conditional switch

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

Alternate for Switch/ifElse

Solution 3 - C#

To complete the thread, here is the syntax with C# 8 and C# 9 :

C# 9 syntax:

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

If you want to specify the ranges :

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

C# 8 syntax:

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

If you want to specify the ranges :

var percent = 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
};

Solution 4 - C#

I would use ternary operators to categorize your switch conditions.

So...

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

Solution 5 - C#

If-else should be used in that case, But if there is still a need of switch for any reason, you can do as below, first cases without break will propagate till first break is encountered. As previous answers have suggested I recommend if-else over switch.

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

Solution 6 - C#

You could have switch construct "handle" ranges by using it in conjunction with a List of your bounds.

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

With this approach ranges can have different spans.

Solution 7 - C#

Interval is constant:

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

Otherwise:

  if else

Solution 8 - C#

As mentioned if-else would be better in this case, where you will be handling a range:

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

Solution 9 - C#

In .Net only Visual Basic allows ranges in switch statements, but in C# there is no valid syntax for this.

Tackling your specific problem in C#, I would solve it thus:

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;

}

To illustrate this further, imagine you have a percentage value.

Using your problem as a template, you might wish this to look like:

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;

}

However, since C# doesn't allow that syntax, here is a solution that C# does allow:

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;

}

It can take a little getting used to, but it's fine once you get it.

Personally, I would welcome switch statements to allow ranges.

The future of C# switch statements

Here are some ideas I had of how switch statements could be improved:

Version A

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

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

    default:
    break;

}

Version B

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

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

    default:
    break;

}

Solution 10 - C#

If you use C/C++, there's no "range" syntax. You can only list all values after each "case" segment. Language Ada or Pascal support range syntax.

Solution 11 - C#

First of all, you should specify the programming language you're referring to. Second, switch statements are properly used for closed sets of options regarding the switched variable, e.g. enumerations or predefined strings. For this case, I would suggest using the good old if-else structure.

Solution 12 - C#

Through switch case it's impossible.You can go with nested if statements.

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

Solution 13 - C#

If the question was about C (you didn't say), then the answer is no, but: GCC and Clang (maybe others) support a range syntax, but it's not valid ISO C:

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

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

Be sure to have a space before and after the ... or else you'll get a syntax error.

Solution 14 - C#

If the range is small you can fall through cases to get to the same point. For example:

int number = 3;
switch (number)
{
    case 1:
    case 2:
    case 3:
    case 4:
        Console.WriteLine("Number is <= 1 <= 4");
        break;
    case 5:
        Console.WriteLine("Number is 5");
        break;
    default:
        Console.WriteLine("Number is anything else");
        break;
}

Solution 15 - C#

In C# switch cases are basically dictionaries on what to do next. Since you can't look up a range in a dictionary, the best you can do is the case ... when statement Steve Gomez mentioned.

Solution 16 - C#

You can use if-else statements with || operators (or-operator) like:

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!... 
   }

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser3022162View Question on Stackoverflow
Solution 1 - C#Steve GomezView Answer on Stackoverflow
Solution 2 - C#AkxayaView Answer on Stackoverflow
Solution 3 - C#A.BaudouinView Answer on Stackoverflow
Solution 4 - C#graphicdivineView Answer on Stackoverflow
Solution 5 - C#GayathriView Answer on Stackoverflow
Solution 6 - C#user3598756View Answer on Stackoverflow
Solution 7 - C#benbaView Answer on Stackoverflow
Solution 8 - C#henrikView Answer on Stackoverflow
Solution 9 - C#WonderWorkerView Answer on Stackoverflow
Solution 10 - C#SliceSortView Answer on Stackoverflow
Solution 11 - C#Andrei NicusanView Answer on Stackoverflow
Solution 12 - C#Joke_Sense10View Answer on Stackoverflow
Solution 13 - C#DarkDustView Answer on Stackoverflow
Solution 14 - C#Christopher John RobbertseView Answer on Stackoverflow
Solution 15 - C#user3406087View Answer on Stackoverflow
Solution 16 - C#Lukas WarsitzView Answer on Stackoverflow