Friday, February 4, 2011

Multiple Cases in Switch:

I believe I've seen this somewhere, but I don't recall if it was a different language, or if I just can't remember the syntax well.

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

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?

Thanks!

  • No, you can't do that in C# without nested ifs - you can in Delphi (Pascal).

  • I've seen some programming languages that use the first syntax and others that use the second, but I don't recall to have ever seen any that allows both.

  • In VB it's like that if I remember correctly. Won't work in C#.

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

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

    Richard C. McGuire : As an addition I wanted to add a link to the C# language specification available on MSDN at http://msdn.microsoft.com/en-us/vcsharp/aa336809.aspx
  • This syntax is from Visual Basic, where you can code something like this:

    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 9 To 10
            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.

    nickf : this is one of the few things I miss about *Basic.
    From Neal
  • Case 1 will work in C#, but you can't have it do something in the intermediate cases and also do something different in the last one - all of the "fall-through" cases have to have only one set of result statements.

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

    
    string s = foo();
    
    switch (s) {
      case "abc": /*...*/ break;
      case "def": /*...*/ break;
    }
    
  • gcc implements an extension to the C language to support sequential ranges:

    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.

    From DGentry
  • You can leave out the newline which gives you:

    case 1: case 2: case 3: break;

    but I consider that bad style.

    /Allan

    From Allan Wind
  • 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.....

    [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()
    {
       ...
    }
    
    From Dr8k
  • .NET Framework 3.5 has got ranges:

    Enumerable.Range from MSDN

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

    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 Action to Action<ParameterType>. If you need return values, use Func<ParameterType, ReturnType>.

    In C# 3.0 there is no easy Partial Application to encapsulate the fact the the case parameter is the same, but you create a little helper method (a bit verbose, 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.

    From volothamp
  • this can work in javascript Switch (value) { case 1||2||3: //job to do break; case 4||5||6: //job to do break; default: //job to do for default case break; }

    From planeur903
  • Hi there, 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;
    }
    

0 comments:

Post a Comment