22

次のコードは、「'st' という名前のローカル変数は、このスコープでは宣言できません。これは、'st' に別の意味を与えるためです。'st' は、'子' スコープで別のものを表すために既に使用されています」:

        var l = new List<string>();
        l.Find(st => st.EndsWith("12"));
        string st = "why this fails?";

これが機能しない理由を理解しています:

        string preParent = "";
        {
            string preParent = "Should fail cause we change the meaning";
        }

以下を実行すると、「CS0103: The name 'postParent' does not exist in the current context」が表示されます。

        {
            string postParent=string.Empty;
        }
        postParent = "Should this work?";

私が得られないのは、コンパイラが postParent がスコープ内にないことを確認できるほどスマートであるのに、子スコープ内で使用される変数と同じ名前の新しい変数を定義させない理由です (これは明らかにアウトです)この時点での範囲)。

コンパイラは、変数の使用を拒否することで単純にスコープを強制していますか? もしそうなら、これは理にかなっています。

===========

編集:

私が興味深いと思うのは、1 つのメソッドで 2 つの子スコープ内で同じ変数を使用する方法です。これは有効です。

        {
            string thisWorks= string.Empty;
        }
        {
            string thisWorks= "Should this work?";
        }

同じレベルにある限り、同じ名前の 2 つの変数を使用できることに少し興味があります (スコープをツリーとして見る場合)。同じ名前の同じクラスの 2 つのメソッドでローカル変数を使用できるため、これは理にかなっています。

postParent 変数を許可しない一方で、コンパイラがこれを区別して許可できることに驚いています。これは技術的な制限ですか、それとも設計上の決定ですか? それが私が本当に達成しようとしていることです;-)

4

2 に答える 2

13

はい、コンパイラはスコープを適用しています。変数のスコープは、それが含まれるレキシカル ブロックであることに注意してください。宣言の時点からではなく、スコープ全体です。

への割り当てがpostParentスコープ外であるため、コンパイラは不平を言っています(ネストされた中括弧のみです)。現在割り当てているポイントで新しい変数を宣言しようとすると、ネストされたブロックで問題が発生します。これは、宣言の前であっても、ネストされたブロックがpostParentスコープに含まれるためです。postParent

スコープは、C# 3.0 仕様のセクション 3.7 で説明されています。

編集: 質問の編集に応答するには。

それはたった2つの簡単なルールです:

  • 同じ名前の別のローカル変数がスコープ内にある場合、ローカル変数を宣言することはできません
  • ローカル変数のスコープは、宣言が発生するブロックです

スコープが宣言の時点でのみ開始されるように言語を設計できたと確信していますが、(言語の複雑さの点で) スコープを単なるブロックと見なす方が簡単だと思います。つまり、同じブロックで宣言されたすべてのローカル変数たとえば、同じスコープを持っています。キャプチャされた変数を考慮すると、生活がずっと簡単になります-キャプチャされるものはスコープに依存し、ネストされたスコープは人生を面白くします...

編集: 言語仕様には、元のラムダ式の例について次のように書かれています - それはセクション 7.14.1 です:

無名関数のオプションの anonymous-function-signature は、無名関数の仮パラメーターの名前と、オプションで型を定義します。無名関数のパラメータのスコープは、anonymous-function-body です。パラメーター リスト (指定されている場合) と共に、無名メソッド本体は宣言空間を構成します。このため、無名関数のパラメーターの名前が、スコープに anonymous-method-expression または lambda-expression を含むローカル変数、ローカル定数、またはパラメーターの名前と一致すると、コンパイル時エラーになります。

それは役に立ちますか?

于 2008-11-17T20:24:50.427 に答える
-2

限られたスコープで変数を宣言し、そのスコープ外で使用しようとしています。コンパイラは、ファイルにアクセスしたくないと想定しているため、ファイル内の別の場所で同じ名前の変数を宣言できます。変数がスコープのすぐ外側にあると仮定するという古い C のトリックを実行しようとしています。たとえば、これは古いバージョンの C/C++ で機能していましたが、現在は機能していません。

for (int i=0; i<10; i++)
{
    cout <<”In the loop i is “&lt;< i << endl;
}
cout << “outside of the loop i is “ << i << endl; //this only compiles with old C/C++ compilers.
于 2008-11-17T20:28:13.133 に答える