C# ラムダ式変数のキャプチャを理解する
C# ラムダ式は、匿名関数を定義するコンパクトな方法を提供します。 ただし、周囲のスコープ内の変数との相互作用は注意が必要な場合があります。
問題: シェア変数の変更
一般的な問題を調べてみましょう。 次のコードは、アクションのリストを作成し、それぞれが異なるカウンター値を出力することを目的としています。
<code class="language-csharp">List<Action> actions = new List<Action>(); for (int i = 0; i < 10; i++) { actions.Add(() => Console.WriteLine(i)); } foreach (Action a in actions) a();</code>
驚くべきことに、これは「10」を 10 回出力します。 ラムダは、その値ではなく、 への 参照i
をキャプチャします。 ループが i
を変更すると、すべてのラムダが最終値を参照します。
解決策: 価値による捕捉
C# は、C 0x の [=]
のような値によるキャプチャ構文を直接サポートしていません。 回避策は、ループのスコープ内にローカル コピーを作成することです:
<code class="language-csharp">for (int i = 0; i < 10; i++) { int copy = i; // Create a local copy actions.Add(() => Console.WriteLine(copy)); }</code>
各ラムダは個別の copy
変数をキャプチャし、各反復で正しい値を保持します。
ローカル コピーが重要な理由
違いは変数のスコープにあります。 参照は同じメモリ位置を共有します。変更はすぐに反映されます。 コピーにより、変数の値キャプチャ時の独立したスナップショットが作成されます。 元の変数に対する後続の変更は、ラムダのキャプチャされたコピーとは無関係です。
以上がC# ラムダ式で変数をキャプチャする際の予期せぬ動作を防ぐにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。