Причина, по которой вам не разрешено определять переменную с тем же именем как в цикле for, так и вне цикла for, заключается в том, что переменные во внешней области действительны во внутренней области. Это означает, что в цикле for будет две переменные «i», если это будет разрешено.
Смотрите: Области MSDN
В частности:
Область действия локальной переменной, объявленной в объявлении локальной переменной (раздел 8.5.1), - это блок, в котором происходит объявление.
и
Областью видимости локальной переменной, объявленной в инициализаторе for оператора for (раздел 8.8.3), является инициализатор for, условие for, итератор for и содержащийся оператор оператора for.
А также: объявления локальных переменных (раздел 8.5.1 спецификации C #)
В частности:
Область локальной переменной, объявленной в объявлении локальной переменной, является блоком, в котором происходит объявление. Ссылка на локальную переменную в текстовой позиции, которая предшествует декларатору локальной переменной локальной переменной, является ошибкой. Объявление другой локальной переменной или константы с тем же именем в рамках локальной переменной является ошибкой времени компиляции.
(Акцент мой.)
Это означает, что объем i
внутри вашего цикла for является циклом for. В то время как область i
вне вашего цикла for - это весь основной метод плюс цикл for. Это означает, что у вас будет два вхождения i
внутри цикла, что недопустимо в соответствии с вышеизложенным.
Причина, по которой вам не разрешено делать, int A = i;
заключается в том, что int i
эта функция предназначена только для использования внутри for
цикла. Таким образом, он больше не доступен вне for
цикла.
Как вы можете видеть, обе эти проблемы являются результатом определения области; первая проблема ( int i = 4;
) приведет к двум i
переменным в пределах for
цикла. Принимая во внимание, int A = i;
что приведет к доступу к переменной, которая выходит за рамки.
Вместо этого вы могли бы объявить i
область действия всего метода, а затем использовать ее как в методе, так и в области видимости цикла. Это позволит избежать нарушения любого из правил.
public static void Main()
{
int i;
for (i = 0; i < 5; i++)
{
}
// 'i' is only declared in the method scope now,
// no longer in the child scope -> valid.
i = 4;
// 'i' is declared in the method's scope -> valid.
int A = i;
}
РЕДАКТИРОВАТЬ :
Конечно, можно изменить компилятор C #, чтобы этот код компилировался вполне корректно. Ведь это действительно так:
for (int i = 0; i < 5; i++)
{
Console.WriteLine(i);
}
for (int i = 5; i > 0; i--)
{
Console.WriteLine(i);
}
Но действительно ли было бы полезно для удобства чтения и поддержки вашего кода иметь возможность писать такой код, как:
public static void Main()
{
int i = 4;
for (int i = 0; i < 5; i++)
{
Console.WriteLine(i);
}
for (int i = 5; i > 0; i--)
{
Console.WriteLine(i);
}
Console.WriteLine(i);
}
Подумайте о возможной ошибке здесь, последняя i
распечатывает 0 или 4? Это очень маленький пример, за которым довольно легко следить и отслеживать, но он определенно намного менее удобен в обслуживании и читаем, чем объявление внешнего i
под другим именем.
NB:
Пожалуйста, обратите внимание, что области видимости C # отличаются от областей видимости C ++ . В C ++ переменные находятся только в области видимости от того, где они объявлены, до конца блока. Что сделало бы ваш код допустимой конструкцией в C ++.