The rules for hiding the C # name are pretty complicated. The language allows you to specify the case that you mentioned, but does not allow many such cases. Cm.
http://ericlippert.com/2009/11/02/simple-names-are-not-so-simple/
for some information on this complex subject.
To answer your specific question: the compiler could certainly detect this conflict. In fact, it detects this conflict:
class P { int x; void M() { x = 123;
An equivalent C ++ program would be legal C ++, because in C ++ a local variable falls into scope at the point of its declaration. In C #, a local variable is in scope throughout its block and uses it before its declaration is illegal. If you try to compile this program, you will get:
error CS0844: Cannot use local variable 'x' before it is declared. The declaration of the local variable hides the field 'P.x'.
See: a local declaration hides a field . The compiler knows this. So why in your case is it not a mistake to hide the field?
Suppose for an argument that this should be an error. If this is also a mistake?
class B { protected int x; } class D : B { void M() { int x; } }
Field x is a member of D through inheritance from B. So this should also be a mistake, right?
Now suppose you have this program from Foo Corporation:
class B { }
and this program released by Bar Corporation:
class D : B { void M() { int x; } }
It compiles. Now suppose Foo Corp updates its base class and sends you a new version:
class B { protected int x; }
Are you telling me that every derived class containing a local variable named x cannot compile now?
That would be terrible. We must allow local variables to shadow members.
And if we let the locals shade the members of the base classes, it would be weird not to let the locals obscure the members of the classes.