Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>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.</p> <p>See: <a href="http://msdn.microsoft.com/en-us/library/aa691132%28v=vs.71%29.aspx" rel="nofollow">MSDN Scopes</a></p> <p>Specifically:</p> <blockquote> <p>The scope of a local variable declared in a local-variable-declaration (Section 8.5.1) is the block in which the declaration occurs.</p> </blockquote> <p>and</p> <blockquote> <p>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.</p> </blockquote> <p>And also: <a href="http://msdn.microsoft.com/en-us/library/aa664742%28v=vs.71%29.aspx" rel="nofollow">Local variable declarations</a> (Section 8.5.1 of the C# specification)</p> <p>Specifically:</p> <blockquote> <p><strong>The scope of a local variable declared in a local-variable-declaration is the block in which the declaration occurs.</strong> It is an error to refer to a local variable in a textual position that precedes the local-variable-declarator of the local variable. <strong>Within the scope of a local variable, it is a compile-time error to declare another local variable or constant with the same name.</strong></p> </blockquote> <p>(Emphasis mine.)</p> <p>Which means that the scope of the <code>i</code> inside your for-loop, is the for-loop. Whereas the scope of the <code>i</code> outside of your for-loop is the entire main method <strong>plus</strong> the for-loop. Meaning you'd have two occurrences of <code>i</code> inside the loop which is invalid according to the above.</p> <p>The reason why you're not allowed to do <code>int A = i;</code> is because <code>int i</code> is only scoped for use within the <code>for</code> loop. Thus it is no longer accessible outside of the <code>for</code> loop. </p> <p>As you can see both of these issues are a result of scoping; the first issue (<code>int i = 4;</code>) would result in two <code>i</code> variables within the <code>for</code> loop scope. Whereas <code>int A = i;</code> would result in access to a variable that is out of scope.</p> <p>What you could do instead is declare <code>i</code> 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.</p> <pre><code>public static void Main() { int i; for (i = 0; i &lt; 5; i++) { } // 'i' is only declared in the method scope now, // no longer in the child scope -&gt; valid. i = 4; // 'i' is declared in the method's scope -&gt; valid. int A = i; } </code></pre> <p><strong>EDIT</strong>:</p> <p>The C# compiler could of course be changed to allow this code to compile quite validly. After all this is valid: </p> <pre><code>for (int i = 0; i &lt; 5; i++) { Console.WriteLine(i); } for (int i = 5; i &gt; 0; i--) { Console.WriteLine(i); } </code></pre> <p>But would it really be beneficial to your code readability and maintainability to be able to write code such as:</p> <pre><code>public static void Main() { int i = 4; for (int i = 0; i &lt; 5; i++) { Console.WriteLine(i); } for (int i = 5; i &gt; 0; i--) { Console.WriteLine(i); } Console.WriteLine(i); } </code></pre> <p>Think about the potential for mistakes here, does the last <code>i</code> 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 <code>i</code> by a different name. </p> <p><strong>N.B:</strong></p> <p>Please note, C#'s scoping rules differ from <a href="http://msdn.microsoft.com/en-us/library/b7kfh662%28v=vs.80%29.aspx" rel="nofollow">C++'s scoping rules</a>. 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++. </p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload