735

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?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
theo
  • 8,501
  • 3
  • 23
  • 22
  • 1
    Is there a reason you don't just use an IF statement (if you are checking a range of ints)? – Eric Schoonover Sep 16 '08 at 01:39
  • 2
    yes charlse, the first way works fine, I've used it in numerous places. It's dirtier than I'd like, but it is useful. I just used those integers as an example. The real data was more varied. An if (1 || 2 || 3 ) {...} else if (4 || 5 || 6) {...} would have worked too, but it's harder to read. – theo Sep 16 '08 at 04:27
  • 6
    why do you consider the latter dirtier than the former. The latter adds yet another meaning to `,` and one that isn't shared with any other c-style language. That would seem much dirtier to me. – Jon Hanna Oct 01 '10 at 14:04
  • You're probably thinking of Delphi/Pascal, which allows the `case i when 1...3: begin end; 4, 5, 7: begin end; 6, 8..10: begin end; else // handle default end;` type syntax. – Ken White Aug 27 '15 at 03:45
  • 4
    **Important Note**. Ranges are supported in switch case starting C# v7 - Please see Steve G.'s [answer](https://stackoverflow.com/a/44848705/465053) – RBT May 18 '18 at 11:47
  • The top example here is actually a lot shorter and easier to read than all the "this is how you would do it in a fancy range based or enumerable range way today" answers that don't fit my super wide screen. I mean. You look at it and it's clear what it does. – robsn Jul 02 '20 at 12:33

26 Answers26

861

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;
}
Julian
  • 886
  • 10
  • 21
Carlos Quintanilla
  • 12,937
  • 3
  • 22
  • 25
  • 4
    The collapsed code gets lengthened to the first example in the question. May as well just do it the way it is in the question. – user4593252 Dec 05 '14 at 19:54
  • 14
    Why bother? The auto indenter in Visual Studio 2013 will revert this to the format in the original question anyway. – Gustav Jun 29 '15 at 16:09
  • 5
    @JeremyChild Maybe because this answer is merely a disguised copy of the question. One of the rare moments I'm down-voting an answer. For real, how did this get so much support? – T_D Mar 09 '16 at 10:10
  • 20
    @T_D it's getting support because it actually answers the question. The OP said, am I missing something... Carlos answered with what he was missing. Seems pretty cut and dried to me. Don't hate that he's got 422 upvotes. – Mike Devenney Mar 30 '16 at 19:42
  • 11
    @MikeDevenney Then you interpreted the question differently, as far as I see the correct answer would be "no, c# doesn't have any syntax for that". If someone asks "is it possible to pour liquid in a glass I'm holding upside down?" the answer should be "no" and not "you can pour liquid up if you look at it upside down and use your imagination", because this answer is all about using imagination. If you use the regular syntax but format it badly it looks like other syntax, with some imagination. Hopefully you get my point... :P – T_D Mar 31 '16 at 13:15
  • 3
    @MikeDevenney For example I have down voted this answer because it is the same answer that Allan Wind gave over two years before this answer! with a bit of unnecessary added fluff.... oh and I upvoted Allans answer ;) – Paul Zahra Apr 04 '17 at 14:03
  • 1
    This will also get long lines if you are using enums, which is mostly the case for switch case statements.... – Mario Garcia Jun 26 '17 at 09:55
  • 2
    I like this because it reflects better what is happening than stacking empty cases above the one that does stuff. I.e. Any of these, do stuff; rather than perhaps a bunch of cases were set up and and the programmer missed doing something in one or more of them. This shows intent better. – Thomas Phaneuf Feb 14 '21 at 19:38
368

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
  • 339,232
  • 124
  • 596
  • 636
  • 5
    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 McGuire Sep 16 '08 at 02:20
  • 1
    User could use some if's (or a table lookup) to reduce the input to a set of enums and switch on the enum. – Harvey Jul 28 '13 at 20:00
  • 4
    I believe this is no longer correct. See https://stackoverflow.com/questions/20147879/switch-case-can-i-use-a-range-instead-of-a-one-number . Also on this very question there's an answer https://stackoverflow.com/a/44848705/1073157 – Dan Rayson May 05 '20 at 21:26
  • Using that many "if" statements is just downright cumbersome. See Misha's answer below for a better method. – Christian Gibbs Aug 25 '21 at 18:12
138

Original Answer for C# 7

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 and would help with the OP's problem.

Example:

int i = 5;

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

// Output: I am between 4 and 6: 5

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

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);
Steve
  • 11,596
  • 7
  • 39
  • 53
  • 4
    This (pattern matching) should generally be best practice when you can use C# 7.x or above, as it is much clearer than the other answers. – UndyingJellyfish Jul 30 '18 at 11:42
  • Is there a way to achieve this with a list of Enums? Where the Enums map to int? – Sigex Dec 12 '18 at 11:21
74

This syntax is from the Visual Basic Select...Case Statement:

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 Is < 1
        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
  • 823
  • 6
  • 4
52

With C#9 came the Relational Pattern Matching. This allows us to do:

switch (value)
{
    case 1 or 2 or 3:
      // Do stuff
      break;
    case 4 or 5 or 6:
      // Do stuff
      break;
    default:
        // Do stuff
        break;
}

In deep tutorial of Relational Patter in C#9

Pattern-matching changes for C# 9.0

Relational patterns permit the programmer to express that an input value must satisfy a relational constraint when compared to a constant value

Esset
  • 916
  • 2
  • 15
  • 17
39

You can leave out the newline which gives you:

case 1: case 2: case 3:
   break;

but I consider that bad style.

Community
  • 1
  • 1
Allan Wind
  • 23,068
  • 5
  • 28
  • 38
22

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

Adam Bellaire
  • 108,003
  • 19
  • 148
  • 163
Luca Molteni
  • 5,230
  • 5
  • 34
  • 42
  • 3
    Good choice. One thing to note, though - Enumerable.Range has arguments `int start` and `int count`. Your examples wont work right the way they were written. You write it as if the second argument is `int end`. For example - `Enumerable.Range(11,20)` would result in 20 numbers starting with 11, and not numbers from 11 to 20. – Gabriel McAdams Aug 02 '12 at 22:46
  • although, if working with an Enum, why not something like? if(Enumerable.Range(MyEnum.A, MyEnum.M){ DoThing(); } else if(Enumerable.Range(MyEnum.N, MyEnum.Z){ DoAnotherThing(); } – David Hollowell - MSFT Mar 06 '14 at 14:22
  • 4
    Note that `Enumerable.Range(11,20).Contains(c)` is equivalent to `for(int i = 11; i < 21; ++i){ if (i == c) return true; } return false;` If you had a large range it would take a long time, while just using `>` and `<` would be quick and constant-time. – Jon Hanna Feb 26 '16 at 14:20
  • An improvement: Having `MySwitchWithEnumerable` return `void` is weak design for this situation. REASON: You've converted an `if-else` to a series of independent statements - that hides the intent, which is that they are mutually-exclusive - only one `action` is executed. Instead return `bool`, with body `if (..) { action(); return true; } else return false;` The calling site then shows the intention: `if (MySwitchWithEnumerable(..)) else (MySwitchWithEnumerable(..));`. This is preferable. However, it is also no longer a significant improvement over your original version, for this simple case. – ToolmakerSteve Jan 17 '17 at 23:24
18

Here is the complete C# 7 solution...

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

It works with strings too...

switch (mystring)
{
   case var s when new[] { "Alpha","Beta","Gamma" }.Contains(s):
      // Do something
      break;
...
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Carter Medlin
  • 11,857
  • 5
  • 62
  • 68
  • 2
    This would mean that you allocate the arrays with each switch statement, right? Wouldn't it be better if we had them as constant variables? – MaLiN2223 Dec 24 '19 at 10:03
  • 2
    Elegant, but it would indeed be good to know if the compiler optimizes this scenario so that repeated invocations don't incur the overhead of the array construction every time; defining the arrays ahead of time is an option, but takes away much of the elegance. – mklement0 Feb 06 '20 at 18:18
  • Create an array and search it just to check if it is a or b or c is very in-efficient! – S.Serpooshan Jun 16 '23 at 14:44
14

The code below won't work:

case 1 | 3 | 5:
// Not working do something

The only way to do this is:

case 1: case 2: case 3:
// Do something
break;

The code you are looking for works in Visual Basic where you easily can put in ranges... in the none option of the switch statement or if else blocks convenient, I'd suggest to, at very extreme point, make .dll with Visual Basic and import back to your C# project.

Note: the switch equivalent in Visual Basic is Select Case.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
none
  • 193
  • 1
  • 9
8

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
  • 1,088
  • 5
  • 11
6

In C# 7 we now have Pattern Matching so you can do something like:

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;
}
Luke T O'Brien
  • 2,565
  • 3
  • 26
  • 38
6

I think this one is better in C# 7 or above.

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

You can also check Range in C# switch case: Switch case: can I use a range instead of a one number

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

Switch case multiple conditions in C#

Or if you want to understand basics of C# switch case

Vikas Lalwani
  • 1,041
  • 18
  • 29
5

In C# 8.0 you can use the new switch expression syntax which is ideal for your case.

var someOutput = value switch
{
    >= 1 and <= 3 => <Do some stuff>,
    >= 4 and <= 6 => <Do some different stuff>,
    _ => <Default stuff>
};
Misha Zaslavsky
  • 8,414
  • 11
  • 70
  • 116
5

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;
}
Cyber Oliveira
  • 8,178
  • 4
  • 28
  • 18
5

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
  • 16,111
  • 8
  • 50
  • 66
4

You can also have conditions that are completely different

            bool isTrue = true;

            switch (isTrue)
            {
                case bool ifTrue when (ex.Message.Contains("not found")):
                case bool ifTrue when (thing.number = 123):
                case bool ifTrue when (thing.othernumber != 456):
                    response.respCode = 5010;
                    break;
                case bool ifTrue when (otherthing.text = "something else"):
                    response.respCode = 5020;
                    break;
                default:
                    response.respCode = 5000;
                    break;
            }
AWhatley
  • 219
  • 1
  • 2
  • 11
4

Actually I don't like the GOTO command too, but it's in official Microsoft materials, and here are all allowed syntaxes.

If the end point of the statement list of a switch section is reachable, a compile-time error occurs. This is known as the "no fall through" rule. The example

switch (i) {
case 0:
   CaseZero();
   break;
case 1:
   CaseOne();
   break;
default:
   CaseOthers();
   break;
}

is valid because no switch section has a reachable end point. Unlike C and C++, execution of a switch section is not permitted to "fall through" to the next switch section, and the example

switch (i) {
case 0:
   CaseZero();
case 1:
   CaseZeroOrOne();
default:
   CaseAny();
}

results in a compile-time error. When execution of a switch section is to be followed by execution of another switch section, an explicit goto case or goto default statement must be used:

switch (i) {
case 0:
   CaseZero();
   goto case 1;
case 1:
   CaseZeroOrOne();
   goto default;
default:
   CaseAny();
   break;
}

Multiple labels are permitted in a switch-section. The example

switch (i) {
case 0:
   CaseZero();
   break;
case 1:
   CaseOne();
   break;
case 2:
default:
   CaseTwo();
   break;
}

I believe in this particular case, the GOTO can be used, and it's actually the only way to fallthrough.

Source

Jiří Herník
  • 2,412
  • 1
  • 25
  • 26
  • 1
    Note that in practice, the `goto` can almost always be avoided (though I don't consider it "terrible" here - it is filling a specific, structured, role). In your example, because you have wrapped the case bodies in functions (a good thing), case 0 can become `CaseZero(); CaseZeroOrOne(); break;`. No `goto` required. – ToolmakerSteve Jan 17 '17 at 23:45
3

If you have a very big amount of strings (or any other type) case all doing the same thing, I recommend the use of a string list combined with the string.Contains property.

So if you have a big switch statement like so:

switch (stringValue)
{
    case "cat":
    case "dog":
    case "string3":
    ...
    case "+1000 more string": // Too many string to write a case for all!
        // Do something;
    case "a lonely case"
        // Do something else;
    .
    .
    .
}

You might want to replace it with an if statement like this:

// Define all the similar "case" string in a List
List<string> listString = new List<string>(){ "cat", "dog", "string3", "+1000 more string"};
// Use string.Contains to find what you are looking for
if (listString.Contains(stringValue))
{
    // Do something;
}
else
{
    // Then go back to a switch statement inside the else for the remaining cases if you really need to
}

This scale well for any number of string cases.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Maxter
  • 716
  • 7
  • 15
3

C# 8 way to do it:

var value = 5;
var output = value switch
{
    1 or 2 or 3 => value + 4,// Do some stuff
    4 => value * 3,// Do some different stuff
    5 => value / 3,// Do some different stuff
    6 => value - 3,// Do some different stuff
    _ => value  // Default stuff
};
ping
  • 663
  • 6
  • 13
2

A more beautiful way to handle that

if ([4, 5, 6, 7].indexOf(value) > -1)
    //Do something

You can do that for multiple values with the same result

Abraham
  • 12,140
  • 4
  • 56
  • 92
1

Just to add to the conversation, using .NET 4.6.2 I was also able to do the following. I tested the code and it did work for me.

You can also do multiple "OR" statements, like below:

            switch (value)
            {
                case string a when a.Contains("text1"):
                    // Do Something
                    break;
                case string b when b.Contains("text3") || b.Contains("text4") || b.Contains("text5"):
                    // Do Something else
                    break;
                default:
                    // Or do this by default
                    break;
            }

You can also check if it matches a value in an array:

            string[] statuses = { "text3", "text4", "text5"};

            switch (value)
            {
                case string a when a.Contains("text1"):
                    // Do Something
                    break;
                case string b when statuses.Contains(value):                        
                    // Do Something else
                    break;
                default:
                    // Or do this by default
                    break;
            }
JeffS
  • 327
  • 7
  • 17
1

An awful lot of work seems to have been put into finding ways to get one of C# least used syntaxes to somehow look better or work better. Personally I find the switch statement is seldom worth using. I would strongly suggest analyzing what data you are testing and the end results you are wanting.

Let us say for example you want to quickly test values in a known range to see if they are prime numbers. You want to avoid having your code do the wasteful calculations and you can find a list of primes in the range you want online. You could use a massive switch statement to compare each value to known prime numbers.

Or you could just create an array map of primes and get immediate results:

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

Maybe you want to see if a character in a string is hexadecimal. You could use an ungly and somewhat large switch statement.

Or you could use either regular expressions to test the char or use the IndexOf function to search for the char in a string of known hexadecimal letters:

        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.

Also, the nice thing about an array map that converts a range of values into actions is that it can be easily changed by code. With hard wired code you can't easily change behaviour at runtime but with an array map it is easy.

Darin
  • 19
  • 1
  • You could also map to lambda expression or a delegate – Conrad Frix Oct 26 '12 at 05:56
  • Good points. One minor comment: I usually find it easier to maintain a list of the values that match a given case, than an array map. The problem with array map is that it is easy to make a mistake. For example, instead of the primes array map of true/falses, simply have a list of primes, and load them into a HashSet for lookup performance. Even if there are more than two cases, usually all but one case is a small list, so build either a HashSet of enums (if sparse) or an array map, in code, from lists of the other cases. – ToolmakerSteve Jan 17 '17 at 23:39
0

We can also use this approach to achieve Multiple cases in switch statement... You can use as many conditions as you want using this approach..

    int i = 209;
    int a = 0;
    switch (a = (i>=1 && i<=100) ? 1 : a){    
    case 1:
        System.out.println ("The Number is Between 1 to 100 ==> " + i);
        break;
    default:
        switch (a = (i>100 && i<=200) ? 2 : a) {
            case 2:
                System.out.println("This Number is Between 101 to 200 ==> " + i);
                break;
        
            default:
                switch (a = (i>200 && i<=300) ? 3 : a) {
                    case 3:
                        System.out.println("This Number is Between 201 to 300 ==> " + i);
                        break;
                
                    default:
                        // You can make as many conditions as you want;
                        break;
                }
        }
        
    }
0

Using new version of C# I have done in this way

public string GetValue(string name)
            {
                return name switch
                {
                    var x when name is "test1" || name is "test2" => "finch",
                    "test2" => somevalue,
                    _ => name
                };
            }
Nic
  • 439
  • 4
  • 14
0

The C#9 example is preferable as it is easiest to read for most developers regardless of their background.

If you are capitated to using an earlier framework that doesn't allow for this syntax then use the format that got over 800 votes.

The prime number example while good academically speaking is an unrealistic business case, I seriously doubt that the over 800 respondents have had a need to find prime number ranges (yes I know it's just an example) and switch between them for their day to day programming.

Lambda expressions and LINQ syntax (less so) examples, while cool, are difficult to read for the uninitiated.

Who knows, maybe Microsoft will add a 'between' keyword in future versions of C# to make ranges easier to read -- that I'd like to see!

Until such time, the C#7 and updated C#9 examples below for ranges work and look best for readability.

Mark Ronollo
  • 174
  • 1
  • 7
-6

For this, you would use a goto statement. Such as:

    switch(value){
    case 1:
        goto case 3;
    case 2:
        goto case 3;
    case 3:
        DoCase123();
    //This would work too, but I'm not sure if it's slower
    case 4:
        goto case 5;
    case 5:
        goto case 6;
    case 6:
        goto case 7;
    case 7:
        DoCase4567();
    }
scone
  • 566
  • 1
  • 4
  • 12
  • 7
    @scone goto breaks a fundamental principal of procedural programming (of which c++ and c# are still rooted in; theyre not pure OO languages (thank God)). Procedural programming has a well defined flow of logic determined by language constructs and method calling conventions (how the runtime stack grows and shrinks). The goto statement circumvents this flow by allowing arbitrary jumping around, basically. – samus Dec 04 '12 at 16:27
  • 1
    I'm not saying it's good style, persay, but it does what the original question was asking for. – scone Sep 10 '15 at 20:11
  • 2
    No, it doesn't "do what the original question was asking for". The original question had code *that worked as is*. They didn't need it fixed. And even if they did, this is a horrible suggestion. Its *less* concise, and uses `goto`. Worse, it is a completely unnecessary use of `goto`, as the original syntax stated by OP does work. The question was whether there was a *more concise* way to give the alternate cases. As people answered *years before you did*, yes there is - if you are willing to put the several cases on one line `case 1: case 2:`, and if the auto-style of editor allows. – ToolmakerSteve Jan 17 '17 at 23:29
  • The only reason goto's are determined to be bad is because some people find it hard to follow logic flow. .Net MSIL (assembled object code) uses goto all over because it is fast, but if .Net code can be written and be just as performant without them it's better to not use them and so you don't get flamed by people like @ToolmakerSteve's condescending reply. – dynamiclynk May 30 '18 at 21:45
  • @wchoward - Please read my reply more carefully. My complaint isn't just about the use of **goto**. I objected because the question **showed code that already works as is**, and this answer a) takes that working code and makes it more verbose, and less-well-structured, **to no benefit**, b) doesn't answer the question. – ToolmakerSteve May 31 '18 at 00:00