I get the following error in Visual Studio 2008:
Error 1 A local variable named 'i' cannot be declared in this scope because it would give a different meaning to 'i', which is already used in a 'child' scope to denote something else
This is my code:
for (int i = 0; i < 3; i++)
{
string str = "";
}
int i = 0; // scope error
string str = ""; // no scope error
I understand that str
ceases to exist once the loop terminates, but I also thought that the scope of i
was confined to the for
loop as well.
So i
has the same scope as a variable declared just outside of the for
loop?
Edit:
Just to be clear, I am using C#. I am debating removing the "C" tag. However, since the correct answer explains the difference between the two, I figure it makes sense to leave both tags.
I had an error in my code comment above:
for (int i = 0; i < 3; i++)
{
string str = "";
}
int i = 0; // scope error
string str = ""; // also scope error,
// because it's equivalent to declaring
// string str =""; before the for loop (see below)
Мне кажется, вы все путаете C++ и C#.
В C++ раньше было так, что область видимости переменной, объявленной в выражении for, была внешней по отношению к блоку, который следовал за ней. Некоторое время назад это было изменено, так что область видимости переменной, объявленной в выражении for, стала внутренней для блока, который за ней следует. C# следует этому более позднему подходу. Но ни то, ни другое не имеет к этому никакого отношения.
Дело в том, что C# не позволяет одной области видимости скрывать переменную с тем же именем во внешней области видимости.
Так, в C++ это раньше было незаконно. Теперь это законно.
for (int i; ; )
{
}
for (int i; ; )
{
}
И то же самое законно в C#. Есть три области видимости, внешняя, в которой 'i' не определена, и две дочерние области видимости, каждая из которых объявляет свою собственную 'i'.
Но вы поступаете следующим образом:
int i;
for (int i; ; )
{
}
Здесь есть две области видимости. Внешняя, которая объявляет 'i', и внутренняя, которая также объявляет 'i'. Это законно в C++ - внешнее 'i' скрыто - но это незаконно в C#, независимо от того, является ли внутренняя область видимости циклом for, циклом while или чем-либо еще.
Попробуйте так:
int i;
while (true)
{
int i;
}
Это та же проблема. C# не позволяет использовать переменные с одинаковыми именами во вложенных областях видимости.
Инкрементор не существует после цикла for.
for (int i = 0; i < 10; i++) { }
int b = i; // this complains i doesn't exist
int i = 0; // this complains i would change a child scope version because the for's {} is a child scope of current scope
Причина, по которой вы не можете повторно объявить i после цикла for, заключается в том, что в IL он фактически объявляет его перед циклом for, поскольку объявления происходят в верхней части области видимости.
Просто некоторая справочная информация: последовательность не входит в это. Есть только идея областей видимости - область видимости метода, а затем область видимости цикла для
. Таким образом, «после завершения цикла» неточно.
Таким образом, ваша публикация читается примерно так же:
int i = 0; // scope error
string str = ""; // no scope error
for (int i = 0; i < 3; i++)
{
string str = "";
}
Я считаю, что такие размышления об этом помогают лучше «вписать» ответы в мою ментальную модель ..
Ага. Синтаксически: новая область видимости находится внутри блока, определенного фигурными строками. Функционально: бывают случаи, когда вы можете захотеть проверить окончательное значение переменной цикла (например, если вы сломались).