Рассмотрите следующий пример кода:
// line #
{ // 1
// 2
{ // 3
double test = 0; // 4
} // 5
// 6
double test = 0; // 7
} // 8
Это дает ошибку
Локальная переменная, названная 'тестом', не может быть объявлена в этом объеме, потому что это дало бы другое значение 'протестировать', который уже используется в 'дочернем' объеме для обозначения чего-то еще
Но я не понимаю почему? Внешняя тестовая переменная запускается в строке 7 а не в строке 2, поэтому где проблема состоит в том, чтобы объявить вторую переменную, названную тестом на строке 4 с объемом, заканчивающимся на строке 5?
Это часто задаваемый вопрос; см. также:
Область действия лямбда-переменной
C # сходит с ума, когда я объявляю переменные с тем же именем, что и в лямбда-выражении
Путаница в области видимости переменной в C #
Ответ: внимательно прочтите сообщение об ошибке. Сообщение об ошибке точно указывает, в чем проблема: вам не разрешено использовать одно и то же простое имя для обозначения двух разных вещей в одном блоке.
Например:
class C
{
int x;
void M()
{
int x;
}
}
Совершенно законно. Обратите внимание, что объем внешнего x перекрывает объем внутреннего x. не незаконно иметь перекрывающиеся области действия с одним и тем же именем в обеих областях.
Это незаконно:
class C
{
int x;
void M()
{
Console.WriteLine(x); // this.x
{
int x;
}
}
}
Опять же, две области видимости с перекрытием x совершенно допустимы. Что незаконно, так это то, что простое имя x используется как две означают две разные переменные в одном блоке - то есть во внешнем блоке M (), который содержит внутренний блок of M.
Программы, в которых одно и то же простое имя используется для обозначения двух разных вещей в одном блоке, сбивают с толку и подвержены ошибкам и, следовательно, незаконный в C #.
Подробнее читайте в моих статьях на эту тему:
http://blogs.msdn.com/b/ericlippert/archive/tags/simple+names/
+1, согласен с вами, но в спеке не так написано. Я уверен, что это упрощает написание компилятора. Кроме того, я думаю, можно было бы возразить, что в любом случае предпочтительнее этого не делать, чтобы код было легче понять.
Переменные находятся в пределах блока , в котором они объявлены, не имеет значения, в какой строке они находятся.
Прочтите о областях в спецификации языка C #.
Из спецификации:
Область действия локальной переменной, объявленной в объявлении локальной переменной ( Раздел 8.5.1 ), - это блок, в котором происходит объявление.
И:
Области видимости могут быть вложенными, а внутренняя область может повторно объявлять значение имени из внешней области. (Это, однако, не снимает ограничения, наложенного Разделом 3.3, согласно которому во вложенном блоке невозможно объявить локальную переменную с тем же именем, что и у локальной переменной во включающем блоке.)