15

I'm using a switch/case statement to handle some updates for a deployed application. Basically, I want to waterfall through the cases to perform the update from the current running version to the newest version.

From Visual Studio yelling at me, I learned that C# does not allow falling through to the next case (exactly what I'm trying to do). From this question, I learned how to do what I want to do. However, it is still apparently an error.

What I've got is

switch (myCurrentVersion)
{
    case null:
    case "":
    case "0":
        UpdateToV1();
        goto case "1";
    case "1":
        UpdateToV2();
}

I'm getting the following error on the line case "1"::

Error 1 Control cannot fall through from one case label ('case "1":') to another

Am I doing something wrong? How can I force it to fall through?

Community
  • 1
  • 1
yoozer8
  • 7,361
  • 7
  • 58
  • 93

4 Answers4

33

You need to add a break statement even if it's the last case:

switch (myCurrentVersion)
{
    case null:
    case "":
    case "0":
        UpdateToV1();
        goto case "1";
    case "1":
        UpdateToV2();
        break;
}
yoozer8
  • 7,361
  • 7
  • 58
  • 93
Mark Byers
  • 811,555
  • 193
  • 1,581
  • 1,452
28

This is a great example of how a poorly worded error message creates confusion. The rule of C# that is actually violated here is not that control has fallen through from one switch section to another; it is that the end point of every switch section must not be reachable. The error, by rights, should have been something like

Endpoint of switch section for case "1" must not be reachable; consider adding 'break;'

When we revisit the semantic analysis of switch statements for the Roslyn project I'll see if we can change the wording on this a bit to be more clear.

For more analysis of this and related issues, see my article on the subject.

yoozer8
  • 7,361
  • 7
  • 58
  • 93
Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
  • 2
    Ok, I have to ask since you're here and I've always wondered; why isn't `break` implicit? Fall-through is not allowed, so why require me to write `break` over and over again? I would love it if fall-through *were* allowed if done so explicitly via some keyword, but short of that, why not save me a bit of typing eh? In that case you would also need to explicitly allow fall-through for empty case blocks, but that seems like a less common scenario. – Ed S. Nov 09 '11 at 23:53
  • 8
    @EdS.: Suppose we make break optional. **People with a C background would then write programs expecting fall-through to work.** But it would not, and the compiler would not tell them otherwise. Making it optional makes the language have a "gotcha". We are working hard to keep the "gotcha" count low in C#. Also, we do *not* require you to write "break" over and over again. You can instead write "throw" or "return" or "goto", or "while(true) {}" -- any of those are just as good as a break as far as the compiler is concerned. – Eric Lippert Nov 10 '11 at 00:13
  • @EdS.: Incidentally, I am frequently asked questions of the form "the compiler could infer that I meant this thing, so why isn't it optional?" Each one is a judgment call; there is no hard-and-fast rule for when an elision is appropriate. For an example or two, see http://stackoverflow.com/questions/2631975/c-sharp-using-consts-in-static-classes/2632844#2632844 and http://stackoverflow.com/questions/6092670/why-are-parentheses-required-on-c-sharp-static-constructors/6099409#6099409 – Eric Lippert Nov 10 '11 at 00:18
  • Sure, that's pretty much what I figured (i.e., keeping it as similar as possible to C semantics). I know it's always a judgement call with things like this. And yeah, I know you can use other statements that would prevent fallthrough, I was just interested in this case. Ok then, thanks for the answer. – Ed S. Nov 10 '11 at 00:21
  • 1
    If you wanted to minimize gotchas, allowing fall-through would have been more appropriate. That's what people with a C background expect. – Suncat2000 May 18 '17 at 18:32
5

You don't have a break in your case "1" branch.

Ed S.
  • 122,712
  • 22
  • 185
  • 265
4

put a break; after UpdateToV2();

Couldnt you get rid of the goto case "1" as it will fall through to that anyway?

Christian
  • 3,708
  • 3
  • 39
  • 60
  • 2
    No, C# doesn't allow that. I think it's because a good chunk of omitted `break;`s are accidental, and they are trying to prevent people from screwing up (although I really think a warning would be far more appropriate than an error). – yoozer8 Nov 09 '11 at 21:15
  • @Jim: Yeah, I think that `break` should have been implicit and fallthrough allowed with the explicit use of some keyword. – Ed S. Nov 09 '11 at 21:31
  • 1
    @Ed S. The reason for requiring the explicit `goto` is so reordering the cases won't change the meaning of your code. – phoog Nov 09 '11 at 23:34
  • 1
    @phoog: Well yes, as it was designed. I am saying that no-fallthrough should be *implicit*, i.e., I don't have to write `break` over and over again, it just works that way. If I want fallthrough then I would be required to use some keyword to allow for it. – Ed S. Nov 09 '11 at 23:51