Cody
Cody

Reputation: 2482

Why are variables that are declared in one case statement in scope for other cases?

Why does the following code compile? I would expect that it would complain about foo not being declared in the second case branch. Does the compiler handle the declaration such that it's in scope for all cases?

using System;

namespace Scratch
{
    class Scratch
    {
        public static void Main()
        {
            var x = 2;
            switch (x)
            {
                case 1:
                    var foo = "one";
                    Console.Out.WriteLine(foo);
                    break;
                case 2:
                    foo = "two"; // is foo in scope here?
                    Console.Out.WriteLine(foo);
                    break;
            }
        }
    }
}

Upvotes: 6

Views: 1624

Answers (4)

Quuxplusone
Quuxplusone

Reputation: 27324

What @JonSkeet said is correct: A "block" in the C/C++/C# sense is not the same thing as a "case" in the logical sense. But he didn't mention the "best practice" for fixing the issue: If you want to declare a variable inside one case of a switch statement, it's good practice to wrap the whole logical "case" in a block. This way the logical "case" and the actual "scope" recognized by the compiler will be one and the same.

public static void Main()
{
    var x = 2;
    switch (x)
    {
        case 1: {  // notice these braces I added
            var foo = "one";
            Console.Out.WriteLine(foo);
            break;
        }
        case 2:
            foo = "two"; // hooray! foo is no longer in scope here
            Console.Out.WriteLine(foo);
            break;
    }
}

Upvotes: 12

ColinCren
ColinCren

Reputation: 615

To make it not compile you can scope with the curly braces like this:

using System;

namespace Scratch
{
    class Scratch
    {
        public static void Main()
    {
        var x = 2;
        switch (x)
        {
            case 1:
            {
                var foo = "one";
                Console.Out.WriteLine(foo);
                break;
            }
            case 2:
            {
                foo = "two"; // is foo in scope here?
                Console.Out.WriteLine(foo);
                break;
            }
        }
    }
}

This forces that the var foo to only exists within that particular scope.

Upvotes: 3

pixelbadger
pixelbadger

Reputation: 1596

In C# variables are scoped at block level. As the block follows the switch statement, foo is indeed in scope in both cases.

Upvotes: 1

Jon Skeet
Jon Skeet

Reputation: 1503090

Why does the following code compile?

Because the language is designed in a brain-dead way in this particular area :(

The scope of a local variable is the block in which it's declared, and it's accessible at any point lexically after the declaration.

No, I wouldn't design the language that way either. I'm not a fan of the design of switch in C#...

Upvotes: 9

Related Questions