это не просто неправильно?
Нет, это совсем не так. Это правильная реализация раздела 7.5.2.1 спецификации C #, «Простые имена, инвариантные значения в блоках».
В спецификации указано:
Для каждого вхождения данного
идентификатор как простое имя в
выражение или декларатор, в пределах
пространство объявления локальной переменной
этого случая, каждый
другое появление того же
идентификатор как простое имя в
выражение или декларатор должны ссылаться на то же
юридическое лицо. Это правило гарантирует, что
значение имени всегда одинаково
в пределах данного блока, блок переключателей,
for-, foreach- или оператор-использование, или
анонимная функция.
Почему C # не может различить две области?
Вопрос бессмысленный; очевидно, компилятор способен различать две области видимости. Если компилятор не может различить две области действия, то как может появиться ошибка ? Сообщение об ошибке говорит , что существуют две разные области действия, и поэтому области были дифференцированы!
Разве первая область IF не должна быть полностью отделена от остальной части метода?
Нет, не должно. Область (и пространство объявления локальной переменной), определенная оператором блока в результате условного оператора, является лексической частью внешнего блока, который определяет тело метода. Поэтому правила относительно содержимого внешнего блока применяются к содержимому внутреннего блока.
Я не могу вызвать var извне if,
поэтому сообщение об ошибке неверно, потому что
первый вар не имеет значения в
вторая сфера.
Это совершенно неправильно. Целесообразно сделать вывод, что только из-за того, что локальная переменная больше не находится в области видимости, внешний блок не содержит ошибки. Сообщение об ошибке правильное.
Ошибка здесь не имеет ничего общего с тем, перекрывает ли область действия любой переменной область действия любой другой переменной; здесь важно только то, что у вас есть блок - внешний блок, в котором одно и то же простое имя используется для обозначения двух совершенно разных вещей. C # требует, чтобы простое имя имело одно значение во всем блоке, который первым его использует .
Например:
class C
{
int x;
void M()
{
int x = 123;
}
}
Это совершенно законно; область видимости внешнего x перекрывает область видимости внутреннего x, но это не ошибка. Что является ошибкой:
class C
{
int x;
void M()
{
Console.WriteLine(x);
if (whatever)
{
int x = 123;
}
}
}
потому что теперь простое имя «x» означает две разные вещи внутри тела M - это означает «this.x» и локальную переменную «x». Разработчикам и разработчикам кода сбивает с толку, когда одно и то же простое имя означает две совершенно разные вещи в одном и том же блоке , так что это недопустимо.
Мы разрешаем параллельным блокам содержать одно и то же простое имя, используемое двумя разными способами; это законно:
class C
{
int x;
void M()
{
if (whatever)
{
Console.WriteLine(x);
}
if (somethingelse)
{
int x = 123;
}
}
}
потому что теперь единственным блоком, который содержит два непоследовательных использования x, является внешний блок, а этот блок не напрямую содержит любое использование "x", только косвенно .