Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Case Statement Block Level Declaration Space in C#

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 been declared) when I try

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

but I can do

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

If C# allowed fall through statements, that would make sense, but it doesn't, and I can't think of a scenario where you can declare a variable in a case statement and use it outside of that block.

like image 621
kemiller2002 Avatar asked Jul 02 '09 14:07

kemiller2002


People also ask

What is switch statement explain with example?

A switch statement allows a variable to be tested for equality against a list of values. Each value is called a case, and the variable being switched on is checked for each switch case.

What is switch in C?

The switch statement in C is an alternate to if-else-if ladder statement which allows us to execute multiple operations for the different possibles values of a single variable called switch variable. Here, We can define various statements in the multiple cases for the different values of a single variable.

What is the syntax of switch statement?

The syntax of the switch statement is:statement(s); break; case constant 2: statement(s);

Can we use variables in switch case in C#?

Important points to remember: In C#, duplicate case values are not allowed. The data type of the variable in the switch and value of a case must be of the same type. The value of a case must be a constant or a literal. Variables are not allowed.


2 Answers

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.

like image 172
Eric Lippert Avatar answered Sep 29 '22 11:09

Eric Lippert


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.

like image 41
NeedHack Avatar answered Sep 29 '22 10:09

NeedHack