ホームページ > バックエンド開発 > C++ > ループのC#Lambda式が最終変数値をキャプチャするのはなぜですか?これをどのように修正できますか?

ループのC#Lambda式が最終変数値をキャプチャするのはなぜですか?これをどのように修正できますか?

Barbara Streisand
リリース: 2025-02-03 08:10:09
オリジナル
794 人が閲覧しました

Why Do C# Lambda Expressions in Loops Capture the Final Variable Value, and How Can This Be Fixed?

c#lambda expression変数ループでのキャプチャを理解する

C#プログラミングの頻繁な問題には、ループ内のラムダ式が含まれます。 Lambda式が変数をキャプチャする方法は、予期しない結果につながる可能性があります。 この問題とその解決策を調べてみましょう。

このコードを検討してください:

<code class="language-csharp">List<Func<int>> actions = new List<Func<int>>();

int variable = 0;
while (variable < 10)
{
    actions.Add(() => variable * 2);
    ++variable;
}

foreach (var act in actions)
{
    Console.WriteLine(act.Invoke());
}</code>
ログイン後にコピー
予想される出力は、偶数のシーケンスです(0、2、4、6、8)。 ただし、実際の出力は5つの10です。 これは、各ラムダの式が、その作成時にその価値ではなく、

への参照をキャプチャするために起こります。 ラムダが呼び出される頃には、variableはすでに10の最終値に達しています。 variable

ソリューション:コピーの作成

これを修正するには、各ラムダ式の範囲内でループ変数のコピーを作成する必要があります。

今、各ラムダ式は、作成時に

の値の独自の独立したコピーをキャプチャし、予想される出力を生成します。

<code class="language-csharp">List<Func<int>> actions = new List<Func<int>>();

int variable = 0;
while (variable < 10)
{
    int copy = variable; // Create a copy of the variable
    actions.Add(() => copy * 2); 
    ++variable;
}

foreach (var act in actions)
{
    Console.WriteLine(act.Invoke());
}</code>
ログイン後にコピー
c#5およびforeachループ

variable

この動作は、C#5以降のバージョンで

ループで懸念が少ないことに注意することが重要です。コンパイラは、この問題を防ぐために、で変数キャプチャを異なる方法で処理します。 ただし、明示的なコピー方法は、古いC#バージョンとの明確さと互換性のためのベストプラクティスのままです。 このアプローチを使用すると、すべてのC#バージョンとループタイプにわたって一貫した動作が保証されます。

以上がループのC#Lambda式が最終変数値をキャプチャするのはなぜですか?これをどのように修正できますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート