7

How can I use more than one constant for a switch case C#? Conceptually, I'm looking for something like this:

switch(n)
{
   case 1,2,3:     //????
   case 4:
   default:
}
John Saunders
  • 160,644
  • 26
  • 247
  • 397
KentZhou
  • 24,805
  • 41
  • 134
  • 200
  • 1
    possible duplicate of [Switch statement fallthrough in C#?](http://stackoverflow.com/questions/174155/switch-statement-fallthrough-in-c) – 3Dave Jun 15 '10 at 18:19
  • 1
    Duplicate of http://stackoverflow.com/questions/174155/switch-statement-fallthrough-in-c – 3Dave Jun 15 '10 at 18:20

6 Answers6

37

A number of answers have stated that "fall through is legal if the case is empty".

This is not correct. This is the wrong way to think about it. This is reasoning as though C# were C, which it is not. In C, every case label has an associated statement list, possibly empty, and control 'falls through' off the end of the statement list. None of this is the case in C#.

In C#, a switch consists of a number of sections, each of which has one or more case labels, and each of which has one or more statements. When you say

switch(x)
{
    case 1:
    case 2:
      M();
      break;
}

It is NOT the situation that there are two switch sections, one for case 1 and one for case 2, and the switch section for case 1 is empty and falls through to the second block. That would be the situation in C, but C# is not C.

In C#, in this example there is ONE switch section. It has TWO labels, and ONE statement list. There is NOT an empty statement list between the case labels; there cannot be because the statement list follows the last label in the section. Let me repeat that: it is not the case that there is an empty statement list there. There is no statement list at all, not even an empty statement list.

This characterization allows us to clearly state the fall-through rule in C# which is "fall through is always illegal", period. Again, it is NOT the case that control "falls through" from the empty statement list of case 1 into case 2. Control never falls through. Control does not fall through here because control never enters the empty statement list after case 1. Control cannot enter that empty statement list because there isn't an empty statement list there in the first place. The statement list does not begin until after case 2.

C# enforces the no-fall-through rule in every switch section, including the last one. This is so that switch sections can be re-ordered arbitrarily, possibly by mechanical tools, without introducing semantic changes in the program.

C# enforces the no-fall-through rule by requiring that the end point of every switch section be unreachable. It is not necessary for a switch section to end in a break. It can end in a break, return, goto, continue, throw, or a detectable infinite loop:

switch(x)
{
    case 1:
        while(true) M();
    case 2:
        return 123;
    case 3:
        throw new Exception();
    case 4:
        M();
        goto case 3;
}

All of the above are legal; there are no breaks.

Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
  • 1
    My initial impression of this was that it was pedantic, since saying, "C# does not support fall-through but allows multiple case statements" and "C# supports fall-through only with empty case statements" are, at first glance, equivalent. However, "C# supports fall-through only with empty case statements" implies that empty case statements are legal, which is not true (demonstrably so, if you use an empty case statement for the last case statement). I suppose the fact that C# has an error when you do it ("`Control cannot fall through from one case label 'case x:' to another`") hints at this. – Brian Jun 16 '10 at 14:30
  • 13
    It's pedantic, but not *merely* pedantic. – Eric Lippert Jun 16 '10 at 16:49
  • You've explained to me why the advice on this always seems contradictory. Thank you @EricLippert! – EleventhDoctor Jun 17 '15 at 08:25
15
switch(n)
{
   case 1:
   case 2:
   case 3:
      // do something
      break;
   default:
      break;
}
drharris
  • 11,194
  • 5
  • 43
  • 56
7

Closest thing to fallthrough switch cases in c#:

switch(n)
{
   case 1:
      // Do something
      goto case 2;
   case 2:
      // Do something
      goto case 3;
   case 3:
      // Do something
     break;
  default:
     break;
}

See here for more info:

http://msdn.microsoft.com/en-us/vcsharp/aa336815.aspx

Gabriel Magana
  • 4,338
  • 24
  • 23
5

You don't, you use fall-through.

switch( n )
{
    case x:
    case y:
    case z:
        DoSomething( );
        break;
    case blah:
        break;
}
Ed S.
  • 122,712
  • 22
  • 185
  • 265
  • 5
    Fall-through is allowed if the case body is empty. – Mehrdad Afshari Jun 15 '10 at 18:18
  • 1
    Yes, it is. You can fall through as long as there is no code in any but the last case. – Ed S. Jun 15 '10 at 18:19
  • Also, just FYI, if you want code in the body, and you want it to fall through, you have to use a GOTO statement, but I suggest against even touching those. – Meiscooldude Jun 15 '10 at 18:22
  • 1
    @Mehrdad: Reasoning as though C# is C is the wrong way to think of it. The correct way to think of it is: (1) a switch section may have one or more switch labels, (2) the end point of every switch section must be unreachable. When you say "case 1 : case 2 : ..." it is not the situation that there is an empty switch section between case 1 and case 2. There isn't ANY switch section at all, empty or not, there. The switch section doesn't even BEGIN until the cases are done. – Eric Lippert Jun 15 '10 at 22:29
  • 3
    @Ed: this is not legal. You cannot have ANY empty switch case body, even the last one. The end point of every switch section must be unreachable. – Eric Lippert Jun 15 '10 at 22:31
  • @Eric: Thanks for the clarification! In fact, my comment was a response to a (now deleted) comment that said "Fall-through is not allowed in C#". – Mehrdad Afshari Jun 15 '10 at 22:33
  • 2
    @Mehrdad Gotta love deleted comments that leave you looking a bit crazy. ;) – drharris Jun 16 '10 at 12:41
  • -1 for claiming you use fall through, when the code you provide as an example has a compiler error: `Error: Control cannot fall through from one case label ('case blah:') to another` – Brian Jun 16 '10 at 14:35
  • Yes, it does. Will fix that, though it really has nothing to do with the question at all, which was answered. – Ed S. Jun 16 '10 at 17:00
  • I was complaining about terminology: The compiler error for the previous version of the code explicitly says that C# case labels do not use fall-through, so your terminology is wrong...and significantly so, since it implies that your previous code was correct, which it was not. See Eric Lippert's answer for discussion of the terminology issue. – Brian Jun 21 '10 at 16:18
  • Ok... call it what you will, but you are definitely 'falling through' cases x and y in the example. So, more accurately, fall through is not allowed if there is any code in the body of the case statement. – Ed S. Jun 21 '10 at 18:06
  • @JennyO'Reilly: The debate here centered around the use of the term 'fall through'. In practice, for us who are not designing a compilers, it is irrelevant. However, Eric Lippert obviously knows what he is talking about, so if you're interested in the details, I'd suggest you read his answer. – Ed S. Apr 07 '16 at 18:59
  • The problem that I have with this answer is, that whoever reads it is going to have a wrong view of how it is working and pass that on to others. While in the end the functionality is the same, the explanation of it is still wrong. – Krisztián Balla Apr 08 '16 at 06:13
  • @JennyO'Reilly: Please explain to me in what ways it is wrong and how that would affect someone's real life application of the solution – Ed S. Apr 08 '16 at 19:40
  • The explanation is wrong, because there is no fall-through and there are no empty cases. There are multiple labels specified for ONE case. The syntax makes it look like a fall-through, but as Eric Lippert pointed out it is not how it works. How would it affect an application? Not at all. But one could think that if it is a fall-trough, you can add statements to "case x" and it would still work the same way. For me this is settled. If you still don't see it my way, there is no way I can "convince" you otherwise. Have a nice day. :-) – Krisztián Balla Apr 09 '16 at 17:14
  • @JennyO'Reilly: So, you're answer to my question is "no" then. You're parroting the same semantic debate we had here nearly six years ago. Yes, it is technically a correct description. Eric Lippert himself explained it out, and I would expect him to be this stringent as it was his job to be a language lawyer. However, the vast majority of people out there have no idea that this is the case and, in fact, it's just confusing as C# directly mimics C's syntax here. The semantics are good to know, nothing wrong with that, but they change absolutely *nothing* in practice. – Ed S. Apr 11 '16 at 18:10
  • @JennyO'Reilly: There's nothing to 'convince me' of here. I understand that my wording is technically incorrect, but the conversation is completely academic as it has no bearing on the problem (or any problem outside of implementing the C# compiler.) – Ed S. Apr 11 '16 at 19:51
  • This is like saying that the sun goes up and down, while in fact the Earth is circulating the sun. For someone who only cares about what it looks like being on Earth, these two things are exactly the same. If you are interested in how it actually works they are completely different. It may only matter if you use your (wrong) knowledge for further development. Then you might be puzzled. – Krisztián Balla Apr 12 '16 at 06:32
  • @JennyO'Reilly: Except that analogy is erroneous because, without a correct model for the motion of celestial bodies through space, one cannot make accurate predictions in the future. In other words, there is an actual, appreciable consequence to being wrong. So, if you think your analogy is correct, show me one (just one!) instance in which the semantic definition makes a difference in actual code. I'm still waiting on this one BTW. If you're going to attempt to mask your pedantry as though it serves some useful purpose you at least have to make up something. – Ed S. Apr 12 '16 at 19:16
  • I thought that I already answered your question and also gave an example by writing: "How would it affect an application? Not at all. But one could think that if it is a fall-trough, you can add statements to "case x" and it would still work the same way." What I mean is that by thinking that it works by falling through you can come to wrong conclusions about how you can use the case statements and then wonder why certain things don't work. I'm sorry if I can't make this any clearer. – Krisztián Balla Apr 13 '16 at 06:11
  • *"What I mean is that by thinking that it works by falling through you can come to wrong conclusions about how you can use the case statements and then wonder why certain things don't work"* - Well that would be a real world issue, right? So give me an example. – Ed S. Apr 13 '16 at 17:03
3

Try this:

switch(n)
{
  case 1:
  case 2:
  case 3:
    //Do Stuff
    break;
  case 4:
    //Do more stuff
    break;
  default:
    //Do standard stuff
    break;
}

Keep in mind this will only work if there is no code in the case 1: or case 2: blocks.i

Ian Jacobs
  • 5,456
  • 1
  • 23
  • 38
  • 1
    As I noted above, this is the wrong way to think of it. There is not an empty block for case 1. There is no block at all, which is different from an empty block! The first switch section block does not begin until after the case 3. – Eric Lippert Jun 15 '10 at 22:30
0

You can do something like this:

switch(n)
{
   case 1: case 2: case 3:     
       break;
   case 4:
       break;
   default:
       break;
}
Juran
  • 177
  • 1
  • 8