views:

3980

answers:

7

Why is it that in a c# switch statement, for a variable used in multiple cases, you only declare it in the first case? For example, the following throws the error "A local variable named 'variable' is already defined in this scope".

switch (Type)
{
    case Type.A:
            string variable = "x";
                break;
    case Type.B:
            string variable = "y";
                break;
}

However, per the logic, the initial declaration should not be hit if the type is Type.B. Do all variables within a switch statement exist in a single scope, and are they created/allocated before any logic is processed?

+11  A: 

I believe it has to do with the overall scope of the variable, it is a block level scope that is defined at the switch level.

Personally if you are setting a value to seomthing inside a switch in your example for it to really be of any benefit, you would want to declare it outside the switch anyway.

Mitchel Sellers
Follow the braces. A variable only exists inside the innermost braces in which the variable is first declared.
Jarrett Meyer
+3  A: 

Yes, the scope is the entire switch block - unfortunately, IMO. You can always add braces within a single case, however, to create a smaller scope. As for whether they're created/allocated - the stack frame has enough space for all the local variables in a method (leaving aside the complexities of captured variables). It's not like that space is allocated during the method's execution.

Jon Skeet
With all due respect, your Skeetness, please don't recommend adding scope to a switch case block. If you need a new scope for that block, odds are you're doing too much in the block. Instead, I suggest you recommend the processing be pushed to a function call.
Randolpho
@Randolpho: I think that's too general a statement to make. It could easily just be three or four lines, but affecting two or three local variables - enough for it to be a pain to refactor out into a method call.
Jon Skeet
+4  A: 

Because their scope is at the switch block. Check here for more info.

itsmatt
+2  A: 

The initialization takes place in the case, but the declaration is effectively done at the top of the scope. (Psuedo-code)

switch (Type)
{
string variable;

    case Type.A:
            variable = "x";
                break;
    case Type.B:
            variable = "y";
                break;
}
James Curran
A: 

I'm not very familiar with C# but in C++ you do not have to use break in between every case statement. You can have case A flow right into case B which would cause the problems that you described above in your question. I do not create variables inside of the cases, if I need a variable in multiple cases I will declare it before the switch.

jsl4980
In C#, they require you to be explicit. You have to either add a break statement, or you could "fall through" with an explicit goto statement that goes to the next label.
Neil Whitaker
A: 

The variables do share scope in the C# compiler, however scope doesn't exist in the same way in IL. As for actual creation / initialization... the .NET memory model lets the compiler move reads / writes a bit as long as simple rules are followed unless the variable is marked as volatile.

jezell
+13  A: 

If you want a variable scoped to a particular case, simply enclose the case in it's own block:

switch (Type)
{
    case Type.A:
            {
            string variable = "x";
            /* do other stuff with variable */
            }
            break;

    case Type.B:
            {
            string variable = "y";
            /* do other stuff with variable */
            }
            break;

}
Michael Burr