Правила сокрытия имен в C # довольно сложны.Язык допускает упомянутое вами дело, но запрещает много подобных случаев.См.
http://ericlippert.com/2009/11/02/simple-names-are-not-so-simple/
для получения дополнительной информации по этому сложному вопросу.
Чтобы ответить на ваш конкретный вопрос: компилятор определенно может обнаружить этот конфликт.Фактически, обнаруживает этот конфликт:
class P
{
int x;
void M()
{
x = 123; // The author intends "this.x = 123;"
int x = 0;
}
}
Эквивалентная программа на C ++ была бы допустимой C ++, потому что в C ++ локальная переменная входит в область действия в точке ее объявления.В C # локальная переменная находится в области действия всего своего блока, и ее использование до объявления недопустимо.Если вы попытаетесь скомпилировать эту программу, вы получите:
error CS0844: Cannot use local variable 'x' before it is declared.
The declaration of the local variable hides the field 'P.x'.
См .: локальная декларация скрывает поле .Компилятор это знает.Так почему же в вашем случае не ошибка скрыть поле?
Давайте предположим, что это должно быть ошибкой.Должна ли это быть также ошибкой?
class B
{
protected int x;
}
class D : B
{
void M()
{
int x;
}
}
Поле x является членом D через наследование от B. Так что это также должно быть ошибкой, верно?
Теперь предположим, что у вас есть эта программа, созданная Foo Corporation:
class B
{
}
, и эта программа, созданная Bar Corporation:
class D : B
{
void M()
{
int x;
}
}
, которая компилируется.Теперь предположим, что Foo Corp обновляет свой базовый класс и отправляет вам новую версию:
class B
{
protected int x;
}
Вы говорите мне, что каждый производный класс, содержащий локальную переменную с именем x, теперь не сможет скомпилироваться?
Это было бы ужасно.Мы должны разрешить локальным переменным затенять членов.
И если мы собираемся разрешить местным жителям скрывать членов базовых классов, было бы очень странно не позволять местным жителям скрывать членов классов.