6

重複の可能性:
c#のスコープと混同されています

C#では、if / else / loopブロックのローカルスコープで定義された変数が、そのブロックの後に外部で定義された変数と競合しているようです。コードの切り取りを参照してください。同等のコードは、C /C++およびJavaで正常にコンパイルされます。これはC#で予想される動作ですか?

public void f(){
  if (true) {
    /* local if scope */
    int a = 1;
    System.Console.WriteLine(a);
  } else {
    /* does not conflict with local from the same if/else */
    int a = 2;
    System.Console.WriteLine(a);
  }

  if (true) {
    /* does not conflict with local from the different if */
    int a = 3;
    System.Console.WriteLine(a);
  }

  /* doing this:
   * int a = 5;
   * results in: Error 1 A local variable named 'a' cannot be declared in this scope
   *  because it would give a different meaning to 'a', which is already used in a 
   *  'child' scope to denote something else
   * Which suggests (IMHO incorrectly) that variable 'a' is visible in this scope
   */

  /* doing this: 
   * System.Console.WriteLine(a);
   * results in: Error 1 The name 'a' does not exist in the current context..
   * Which correctly indicates that variable 'a' is not visible in this scope
   */
}
4

5 に答える 5

5

はい、これがC#の仕組みです。

スコープを宣言するとき、外部スコープからのローカル変数も認識されます。スコープ内のローカル変数が外部からのローカル変数をオーバーライドする必要があることを限定する方法はありません。

于 2012-08-21T18:20:53.620 に答える
4

宣言の順序(ブロックのa で再宣言)に関心があるようです。if

ブロックのに宣言されている場合を考えてみましょう。if次に、それらのブロックの範囲内で使用可能であることが期待されます。

int a = 1;

if(true)
{
  var b = a + 1; // accessing a from outer scope
  int a = 2; // conflicts
}

コンパイル時に「まだスコープ内にない」という概念は実際にはありません。

実際には、中かっこだけで内部スコープを作成できます。

{
   int a = 1;
}

if(true)
{
   int a = 2; // works because the a above is not accessible in this scope
}
于 2012-08-21T18:23:17.837 に答える
3

これは正常な動作です。

Sam Ngは、これについて少し前に素敵なブログ投稿を書きました:http: //blogs.msdn.com/b/samng/archive/2007/11/09/local-variable-scoping-in-c.aspx

于 2012-08-21T18:23:09.100 に答える
3

すでにいくつかの良い答えがありますが、これを明確にするために C# 4 言語仕様を調べました。

スコープについては、§1.24 で読むことができます。

スコープは入れ子にすることができ、内側のスコープは外側のスコープから名前の意味を再宣言できます (ただし、これは、入れ子になったブロック内でローカル変数を囲んでいるブロック内のローカル変数と同じ名前)。

そして、これは §1.20 で引用された部分です。

宣言は、宣言が属する宣言空間で名前を定義します。オーバーロードされたメンバー (§1.23) を除き、宣言空間に同じ名前のメンバーを導入する 2 つ以上の宣言があると、コンパイル時エラーになります。宣言スペースに同じ名前の異なる種類のメンバーを含めることはできません

[...]

関数メンバーまたは無名関数の本体として、または本体内で発生するブロックは、それらの関数によってパラメーター用に宣言されたローカル変数宣言スペース内にネストされることに注意してください。

于 2012-08-21T18:43:30.433 に答える
0

はい。local ステートメント内で変数を定義しているため、これは予期されることです。クラス レベルで変数を定義すると、異なる結果が得られます。

于 2012-08-21T18:21:24.563 に答える