CS0103 and CS0136 with pattern matching

I'm a little bit confused. Why from one side I become CS0103(variable does not exist) and from another side CS0136(with own words - variable already exists) and declaration of variables with same names in switch works?

This works:

var obj = new object();
switch (obj)
{
    case string str:
        break;

    case object str:
        break;
}

Here I become compilation error CS0103 "The name ' ' does not exist in the current context":

var obj = new object();
switch (obj)
{
    case string str: 
        break;
}
if (str == null) { } //CS0103

Here I become compilation error CS0136:

var obj = new object();
switch (obj)
{
    case string str: //<--- CS0136
        break;
}
string str = "";

CS0136: A local variable named 'var' cannot be declared in this scope because it would give a different meaning to 'var', which is already used in a 'parent or current/child' scope to denote something else

CS0103: The name 'identifier' does not exist in the current context

Jon Skeet
people
quotationmark

There are three rules at play here:

  • The scope of a local variable is normally the entire block in which it's declared. The variables introduced via pattern matching in switch statements are slightly narrower than that, which is how you're able to have patterns of both object str and string str - but you don't need that to demonstrate these specific errors.
  • You can't use a variable outside its scope
  • You can't declare one local variable in the scope of another with the same name.

You don't need pattern matching to demonstrate this. Here's a simple method which gives the CS0103 error:

void Method()
{
    {
        // Scope of str is the nested block.
        string str = "";
    }
    // str isn't in scope here, so you can't refer to it;
    // second bullet point
    if (str == "") {}
}

And here's an example of CS0136:

void Method()
{
    {
        // Can't declare this variable, because the str variable
        // declared later is already in scope
        string str = "";
    }
    // Scope of this variable is the whole method
    string str = "";
}

people

See more on this question at Stackoverflow