15

I was reading an interesting article here and it made an interesting point about the 'case' statement in vb.net vs the 'switch' statement in C#, which I've pasted below:

The following Visual Basic Select Case statement can't be represented in C# with a single switch statement:

Dim Condition As Integer = 55
Select Case Condition
  Case 1, 3 To 5, 10, 12, 14, Is > 50
    'value 55 executes code here
  Case Else
    'values <1, 2, 6-9, 11, 13, 15-49
End Select

I've always found the switch statement in C#, with dropthrough and consequentrequirements for a break in each case, to be a bit unwieldy. Is there any reason they haven't enhanced the switch command to allow these situations? When would dropthrough be useful anyway? Anyone know of any extensions of the construct to allow more flexibility?

Cheers

Community
  • 1
  • 1
Glinkot
  • 2,924
  • 10
  • 42
  • 67
  • 3
    The `switch` construct is very limited in C-dialect languages. This is arguably because switch (on some small value, say 0-255) *could* be turned into a direct jump and avoid conditionals entirely -- coupled with fall-through semantics (which C# does not have), it was useful for ("ASCII") character processing and the like. The real question is -- why do neither C# nor VB.NET support a more general (and much higher-level) *pattern matching* construct like F#, Scala, or Haskell? :-) –  May 04 '11 at 23:56
  • 1
    I'm pretty sure that a switch statement (in C#) with more than 7 elements is actually converted to a Dictionary (hash table) at compile time. Hashing a predicate like 'Is > 50' would be a very interesting problem. – Jon May 05 '11 at 00:16
  • 5
    I don't understand the close votes. This is a valid question. There are historical reasons why VB.NET has more functionality here than C# and there are reasons why the greater functionality can't be implemented internally with the same efficiency, but there really is nothing stopping the compiler from implementing this type of functionality even when the CLR doesn't. It would be nice to hear from someone on the compiler team or knowledge of any discussion on this matter as to why this really isn't implemented. Perhaps it's as simple as C# developers really don't care about this functionality. – Samuel Neff May 05 '11 at 00:24
  • @Samuel Neff - I would have also voted to close. This is a discussion point, not a question. It's interesting but (again) *it's not a real question*. – Kirk Broadhurst May 05 '11 at 01:15

3 Answers3

19

In C# you can only use distinct values in cases. This makes it more limited, but on the other hand it makes it faster because it can be implemented using a hash lookup.

The switch syntax has been made more restricted in C# than in C/C++. You can still do the same things, but a fall through is not made implicitly, you have to write a specific jump to the next case. The reason for this restriction is that it's much more common to do fall through by mistake than intentionally.

In C# you would need an if statement in the default case to handle the ranges:

int condition = 55;
switch (condition) {
  case 1:
  case 3:
  case 4:
  case 5:
  case 10:
  case 12:
  case 14:
    // values 1, 3-5, 10, 12, 14
    break;
  default:
    if (condition > 50) {
      // value 55 executes code here
    } else {
      // values <1, 2, 6-9, 11, 13, 15-49
    }
    break;
}
Guffa
  • 687,336
  • 108
  • 737
  • 1,005
  • 1
    Thanks for the note. This to me is indeed the answer; I had suspected something architectural or performance based was driving the difference. When you mention fallthrough not being implicit though, I thought the need for a break meant that fallthrough would happen implicitly? Thanks for the note. – Glinkot May 05 '11 at 02:35
6

I remember a uni lecturer once telling us the only useful thing he had ever found to do with fall through was write out the lyrics to the twelve days of christmas.

Something along these lines

for (int i = 1; i <= 5; i++) {
    Console.WriteLine("On the " + i + " day of christmast my true love gave to me");
    switch (i) {
    case 5:
        Console.WriteLine("5 Gold Rings");
        goto case 4;
    case 4:
        Console.WriteLine("4 Colly Birds");
        goto case 3;
    case 3:
        Console.WriteLine("3 French Hens");
        goto case 2;
    case 2:
        Console.WriteLine("2 Turtle Doves");
        goto case 1;
    case 1:
        Console.WriteLine("And a Partridge in a Pear Tree");
        break;
    }
    Console.WriteLine("-");
}

10 years later I tend to agree with him. At the time we were doing java which does fall through, had to fake it for C#.

Chris Sainty
  • 9,086
  • 1
  • 26
  • 31
  • 1
    Lol, I agree. I can't think of a logical situation where the fall through has utility, but there are plenty of similar cases where that's been true and others have had great examples. To me (in absence of the gotos above), if you can only have distinct cases rather than ranges/other sophisticated criteria, when would you want to trigger more than one? Thanks for the note! – Glinkot May 05 '11 at 02:32
  • 1
    Fall-through can sometimes be useful in state machines where something special must happen before the first time the state machine runs a piece of code. The `FIRST_FOO` case performs the appropriate initialization, advances the state to `MORE_FOO`, and uses an explicitly-commented fall through to the `MORE_FOO` code which process the first invocation as well as subsequent ones. – supercat May 07 '13 at 20:57
2

Drop through is allowed for the special case of matching multiple cases, but the comparative and range cases aren't allowed. So:

int condition = 55;
switch (condition) {
  case 1: case 3: case 4: case 5: case 10: case 12: case 14:
    // value 55 doesn't execute here anymore

  default:
    //values <1, 2, 6-9, 11, 13, >14
}
Andrew Cooper
  • 32,176
  • 5
  • 81
  • 116
  • 1
    Thanks for that. The example does really illustrate the limited usage of the construct; the point above about it being hashed by the compiler makes a lot of sense though. – Glinkot May 05 '11 at 02:33