Is it just wrong?
No, thatβs not at all. This is the correct implementation of section 7.5.2.1 of the C # specification, "Simple Names, Values ββof Invariants in Blocks".
The specification states:
For each case of a given identifier as a simple name in an expression or declarator within the local space of the declaration of variable variables of this event, each other occurrence of the same identifier as a simple name in an expression or declarator must refer to the same organization. This rule ensures that the name value is always the same within a given block, switch block, for-, foreach- or use-statement or anonymous function.
Why can't C # distinguish between two areas?
The question is meaningless; Obviously, the compiler is able to distinguish between two areas. If the compiler could not distinguish between the two areas, then how could an error occur? The error message states that there are two different scopes, so the ranges were differentiated!
If the first IF region cannot be completely separated from the rest of the method?
No, it should not. The area (and local variable declaration space) defined by the block operator as a result of the conditional statement is lexically part of the external block that defines the body of the method. Therefore, the rules on the contents of the external block are applied to the contents of the internal block.
I cannot call var from outside if, so the error message is incorrect because the first var is not related to the second area.
This is completely wrong. It is understandable that only because the local variable is no longer in scope does the external block contain no errors. The error message is correct.
The error here has nothing to do with the fact that the scope of any variable overlaps the scope of any other variable; the only thing that matters here is that you have a block - an external block - in which the same simple name is used to mean two completely different things. C # requires that a simple name has one value in the whole block that first uses it.
For example:
class C { int x; void M() { int x = 123; } }
This is completely legal; the outer x region overlaps the inner x region, but this is not an error. Mistake:
class C { int x; void M() { Console.WriteLine(x); if (whatever) { int x = 123; } } }
because now the simple name "x" means two different things inside the body of M - it means "this.x" and the local variable "x". This confuses developers and code developers when the same simple name means two completely different things in one block, so this is illegal.
We allow parallel blocks to contain the same simple name, used in two different ways; it is legal:
class C { int x; void M() { if (whatever) { Console.WriteLine(x); } if (somethingelse) { int x = 123; } } }
because now the only block that contains two inconsistent uses of x is the external block, and this block does not contain the direct use of "x", only indirectly .