24

xパラメータの動作が不安定なのはなぜですか?

  1. 例 1 - 現在のコンテキストには存在しません。
  2. 例 2 - x「子」スコープで定義されているため、再利用できません。
  3. 例 3 - 結構です。これは私が混乱している部分です。おそらく別の「子」スコープですか?

例 1 :

List<int> list = new List<int> { 1, 2, 3, 4, 5 };
var result = list.Where(x => x < 3);
Console.Write(result.ElementAt(x));

このコンパイル時エラーを作成します。

名前「x」は現在のコンテキストに存在しません

私が期待するもの。

例 2 :

List<int> list = new List<int> { 1, 2, 3, 4, 5 };
var result = list.Where(x => x < 3);
int x = 1;
Console.Write(result.ElementAt(x));

次のコンパイル時エラーが発生します。

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

この質問で回答されているスコープを理解しています.Is there a reason for C#'s reuse of the variable in a foreach? . しかし、これは私が今まで見たことのないものです。さらに、C# でのラムダ変数のスコープは何ですか? 、不完全または間違っています。

例 3 :

List<int> list = new List<int> { 1, 2, 3, 4, 5 };
List<string> stringList = new List<string> { "A", "B" };
var result = list.Where(x => x < 3);
var result2 = stringList.Where(x => x != "A");

Console.Write(result2);

エラーは発生しませんでした。


受け入れられた回答で、Eric Lippert からのこれらのブログ投稿は、何が起こっているのかを理解するのに役立ちました。まだ混乱している場合:

宣言スペース

簡単な名前

4

3 に答える 3

19

ではExample 1、x は ladba 式のローカル スコープで定義されており、3 行目には表示されません。

ではExample 2、同じ宣言スコープで「x」という名前の 2 つの変数を宣言しました (可視性は異なります)。

ラムダまたは匿名メソッドを使用すると、実行中のスコープを「キャプチャ」します。ラムダ定義と同じスコープにローカル x がある場合、その x を「キャプチャ」して、ラムダがアクセスできるものにプルします。したがって、「x」の 2 つの定義が生成されます。ラムダで宣言したものは、他の方向ではキャプチャされないため、ラムダの外では見えません。

ではExample 3、ラムダの外側のラムダのみにローカルな変数を使用しておらず、同じ宣言スコープで同じ名前を付けていません。

于 2012-05-14T17:10:47.450 に答える
5

子スコープ (例 3) は同じ変数を使用できますが、親と子は変数を再宣言できません。

forで同じことができます:

// Child scopes
for (int i = 1; i < 10; i++){ /* do something */ }
for (int i = 1; i < 10; i++){ /* do something else */ }

これは失敗します:

// Child and parent
for (int i = 1; i < 10; i++){ /* do something */ }
int i = 33;
于 2012-05-14T17:16:56.307 に答える
3

見た目ほど複雑ではありません。

ラムダ式のパラメーターを定義する場合、パラメーターはラムダ式のスコープ内でのみ有効です

(int x) =>
{
   //x is only valid inside this scope
}

ラムダ式と同じスコープで定義された 2 番目の変数がある場合、この 2 番目の変数はラムダ式のスコープでも有効であるため、エラーが発生します。

void Foo()
{

 int y;

 //y is valid in the scope of foo

 (int x) =>
 {
    //x is only valid inside this scope
    //y is valid in the scope of foo and the lamda expression
 }
}

3 番目の例では、2 つの異なるラムダ式があるため、2 つの異なるスコープがあります。

于 2012-05-14T17:17:57.280 に答える