Case Statement Block Level Declaration Space in C#

前端 未结 5 1810
走了就别回头了
走了就别回头了 2020-11-29 12:18

Is there a reason I am missing that a block within a case statement isn\'t considered a block level declaration space?

I keep getting an error (variable has already

相关标签:
5条回答
  • 2020-11-29 12:51

    UPDATE: This question was used as the inspiration for this blog post; see it for further details.

    http://ericlippert.com/2009/08/13/four-switch-oddities/

    Thanks for the interesting question.


    There are a number of confusions and mis-statements in the various other answers, none of which actually explain why this is illegal. I shall attempt to be definitive.

    First off, to be strictly correct, "scope" is the wrong word to use to describe the problem. Coincidentally, I wrote a blog post last week about this exact mis-use of "scope"; that will be published after my series on iterator blocks, which will run throughout July.

    The correct term to use is "declaration space". A declaration space is a region of code in which no two different things may be declared to have the same name. The scenario described here is symptomatic of the fact that a switch section does not define a declaration space, though a switch block does. Since the OP's two declarations are in the same declaration space and have the same name, they are illegal.

    (Yes, the switch block also defines a scope but that fact is not relevant to the question because the question is about the legality of a declaration, not the semantics of an identifier lookup.)

    A reasonable question is "why is this not legal?" A reasonable answer is "well, why should it be"? You can have it one of two ways. Either this is legal:

    switch(y)
    {
    case 1:  int x = 123; ... break;
    case 2:  int x = 456; ... break;
    }
    

    or this is legal:

    switch(y)
    {
    case 1:  int x = 123; ... break;
    case 2:  x = 456; ... break;
    }
    

    but you can't have it both ways. The designers of C# chose the second way as seeming to be the more natural way to do it.

    This decision was made on July 7th, 1999, just shy of ten years ago. The comments in the notes from that day are extremely brief, simply stating "A switch-case does not create its own declaration space" and then giving some sample code that shows what works and what does not.

    To find out more about what was in the designers minds on this particular day, I'd have to bug a lot of people about what they were thinking ten years ago -- and bug them about what is ultimately a trivial issue; I'm not going to do that.

    In short, there is no particularly compelling reason to choose one way or the other; both have merits. The language design team chose one way because they had to pick one; the one they picked seems reasonable to me.

    0 讨论(0)
  • 2020-11-29 12:51

    You could just declare the variable outside the scope of the switch statement.

    var someVariable;
    
    switch();
    case x:   
    someVariable = 42;
    break; 
    case y:     
    someVariable = 40;
    break;
    
    0 讨论(0)
  • 2020-11-29 12:54

    Ah - you don't have fall through, but you can use goto to jump to another labelled case block. Therefore the blocks have to be within the same scope.

    0 讨论(0)
  • 2020-11-29 13:07

    You could also do:

    case x:
      {var someVariable = 42;}
    break;
    case y: 
       {var someVariable = 40;}
    break;
    

    Essentially the braces create the lexical scope, so without the braces, someVariable is loaded into the symbol table twice. I believe this choice is likely made simply to avoid confusion, and possibly to avoid adding complexity to the building of the symbol table.

    0 讨论(0)
  • 2020-11-29 13:12

    Because cases aren't blocks, there are no curly braces denoting the scope. Cases are, for lack of a better word, like labels.

    You're better off declaring the variable outside the switch() statement and using it thereafter. Of course, in that scenario, you won't be able to use the var keyword, because the compiler won't know what type to initialize.

    0 讨论(0)
提交回复
热议问题