forループ内とforループ外の両方で同じ名前の変数を定義できないのは、外側のスコープの変数が内側のスコープで有効であるためです。これが許可された場合、forループ内に2つの「i」変数が存在することを意味します。
参照:MSDNスコープ
具体的には:
local-variable-declaration(セクション8.5.1)で宣言されたローカル変数のスコープは、宣言が行われるブロックです。
そして
forステートメントのforイニシャライザ(セクション8.8.3)で宣言されたローカル変数のスコープは、forイニシャライザ、for条件、forイテレータ、およびforステートメントに含まれるステートメントです。
また、ローカル変数宣言(C#仕様のセクション8.5.1)
具体的には:
local-variable-declarationで宣言されたローカル変数のスコープは、宣言が行われるブロックです。ローカル変数のlocal-variable-declaratorの前にあるテキストの位置でローカル変数を参照すると、エラーになります。ローカル変数のスコープ内で、同じ名前の別のローカル変数または定数を宣言すると、コンパイル時エラーになります。
(エンファシス鉱山。)
つまり、i
forループ内のスコープはforループです。i
forループの外側のスコープは、メインメソッド全体と forループが。の2つの発生があることを意味しますi
上記のように無効なループ内。
あなたが許可されていないint A = i;
理由int i
は、for
ループ内での使用に限定されているためです。したがって、for
ループの外側からはアクセスできなくなります。
ご覧のとおり、これらの問題は両方ともスコープの結果です。最初の問題(int i = 4;
)はi
、for
ループスコープ内に2つの変数をもたらします。一方int A = i;
、スコープ外の変数にアクセスすることになります。
代わりi
に、メソッド全体をスコープとするように宣言し、それをメソッドとforループスコープの両方で使用できます。これにより、どちらのルールにも違反しなくなります。
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
、別の名前でアウターを宣言するよりも、保守性と可読性がはるかに低くなります。
注意:
C#のスコープルールはC ++のスコープルールとは異なります。C ++では、変数は、宣言された場所からブロックの終わりまでの範囲内にのみ存在します。これにより、コードがC ++で有効な構成になります。