BrokenGlass's answer is of course correct; you are not looking at the field in the first place. The local hides the field.
However, I note that no one has addressed this portion of your question:
I'm actually surprised that it compiles. I would have expected to see some sort of warning about having two variables with the same name.
The C# compiler does not issue an error or warning in that case because doing so would create a form of "brittle base class failure". Suppose you have this code:
class B { }
class D : B
{
void M()
{
int x;
...
where B is made by one team in your organization, and D is made by an entirely different team. Then one day the maintainers of B decides to add a feature that needs a protected field:
class B { protected int x; }
When you recompile D, should it give an error? If it does, then someone on a completely different team just broke your code! C# has been carefully designed to minimize (though not eliminate) this kind of breakage.
Note that C# does give an error if you re-use x to mean two different things in the same code block. For example:
class B { protected int x; }
class D : B
{
void M()
{
x = 123; // meaning this.x inherited from B
if (whatever)
{
int x = 10;
...
That's illegal because now in the body of M, the simple name x
is used to mean both this.x
and local variable x
. Because this is potentially confusing and a bad programming practice, we make it an error. However, if you really want that then you can eliminate the error by ensuring that the usages are in *entirely separate blocks:
class B { protected int x; }
class D : B
{
void M()
{
{
x = 123; // meaning this.x inherited from B
}
if (whatever)
{
int x = 10;
Now the blocks do not overlap and therefore the compiler assumes that you know what you are doing and allows the code to compile.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…