views:

11299

answers:

13

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!

+1  A: 

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

KiwiBastard
A: 

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.

Alexandre Brasil
A: 

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

David Thibault
+11  A: 

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.

Brian R. Bondy
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
Richard C. McGuire
+7  A: 

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.

Neal
this is one of the few things I miss about *Basic.
nickf
A: 

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.

cori
+1  A: 

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;
}
Leonardo Constantino
+2  A: 

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.

DGentry
A: 

You can leave out the newline which gives you:

case 1: case 2: case 3: break;

but I consider that bad style.

/Allan

Allan Wind
A: 

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()
{
   ...
}
Dr8k
+2  A: 

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

volothamp
A: 

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

planeur903
A: 

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