Variable declared in for-loop is local variable?
The reason you are not allowed to define a variable with the same name in both the for-loop as well as outside the for-loop is because variables in the outer-scope are valid in the inner-scope. Meaning that there would be two 'i' variables within the for-loop if this was allowed.
See: MSDN Scopes
Specifically:
The scope of a local variable declared in a local-variable-declaration (Section 8.5.1) is the block in which the declaration occurs.
and
The scope of a local variable declared in a for-initializer of a for statement (Section 8.8.3) is the for-initializer, the for-condition, the for-iterator, and the contained statement of the for statement.
And also: Local variable declarations (Section 8.5.1 of the C# specification)
Specifically:
The scope of a local variable declared in a local-variable-declaration is the block in which the declaration occurs. It is an error to refer to a local variable in a textual position that precedes the local-variable-declarator of the local variable. Within the scope of a local variable, it is a compile-time error to declare another local variable or constant with the same name.
(Emphasis mine.)
Which means that the scope of the i
inside your for-loop, is the for-loop. Whereas the scope of the i
outside of your for-loop is the entire main method plus the for-loop. Meaning you'd have two occurrences of i
inside the loop which is invalid according to the above.
The reason why you're not allowed to do int A = i;
is because int i
is only scoped for use within the for
loop. Thus it is no longer accessible outside of the for
loop.
As you can see both of these issues are a result of scoping; the first issue (int i = 4;
) would result in two i
variables within the for
loop scope. Whereas int A = i;
would result in access to a variable that is out of scope.
What you could do instead is declare i
to be scoped to the entire method, and then use it in both the method as well as the for-loop scope. This will avoid breaking either rule.
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;
}
EDIT:
The C# compiler could of course be changed to allow this code to compile quite validly. After all this is valid:
for (int i = 0; i < 5; i++)
{
Console.WriteLine(i);
}
for (int i = 5; i > 0; i--)
{
Console.WriteLine(i);
}
But would it really be beneficial to your code readability and maintainability to be able to write code such as:
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);
}
Think about the potential for mistakes here, does the last i
print out 0 or 4? Now this is a very small example, one which is quite easy to follow and track but it is definitely a lot less maintainable and readable than having declared the outer i
by a different name.
N.B:
Please note, C#'s scoping rules differ from C++'s scoping rules. In C++ variables are only in scope from where they are declared until the end of the block. Which would make your code a valid construct in C++.
J.Kommer's answer is correct: briefly, it is illegal for a local variable to be declared in a local variable declaration space that overlaps another local variable declaration space that has a local of the same name.
There is an additional rule of C# that is violated here as well. The additional rule is that it is illegal for a simple name to be used to refer to two different entities inside two different overlapping local variable declaration spaces. So not only is your example illegal, this is illegal too:
class C
{
int x;
void M()
{
int y = x;
if(whatever)
{
int x = 123;
Because now the simple name "x" has been used inside the local variable declaration space of "y" to mean two different things -- "this.x" and the local "x".
See http://blogs.msdn.com/b/ericlippert/archive/tags/simple+names/ for more analysis of these issues.
There is a way of declaring and using i
inside the method after the loop:
static void Main()
{
for (int i = 0; i < 5; i++)
{
}
{
int i = 4;
int A = i;
}
}
You can do this in Java (it might originate from C I'm not sure). It is of course a bit messy for the sake of a variable name.