6

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;
            }
        }
    }
}
Cody
  • 2,467
  • 2
  • 21
  • 30
  • might want to see http://stackoverflow.com/questions/11199338/using-a-switch-statement-to-set-the-value-of-one-particular-variable-only – nawfal Dec 29 '13 at 23:54

4 Answers4

10

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;
    }
}
Quuxplusone
  • 23,928
  • 8
  • 94
  • 159
9

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#...

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
3

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.

ColinCren
  • 595
  • 3
  • 13
1

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

pixelbadger
  • 1,556
  • 9
  • 24