Maison >développement back-end >C++ >Pourquoi les expressions C # Lambda dans les boucles capturent-elles la même variable, et comment peut-elle être résolue?

Pourquoi les expressions C # Lambda dans les boucles capturent-elles la même variable, et comment peut-elle être résolue?

Barbara Streisand
Barbara Streisandoriginal
2025-02-03 07:46:13294parcourir

Why Do C# Lambda Expressions in Loops Capture the Same Variable, and How Can This Be Resolved?

Comprendre C # Lambda Expression Capture en boucles et sa solution

C # Les expressions de lambda dans les boucles présentent un piège commun: ils capturent la même variable, conduisant à des résultats inattendus. Cela se produit parce que l'expression de lambda ne capture pas la valeur de la variable au moment de sa création, mais plutôt une référence à la variable elle-même. Considérez cet exemple:

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

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

foreach (var act in actions)
{
    Console.WriteLine(act.Invoke());
}</code>

Au lieu de la sortie attendue (0, 2, 4, 6, 8), le code sort cinq 8s. En effet, toutes les expressions lambda font référence à la valeur finale de variable (qui est 10 une fois la boucle terminée), pas sa valeur au moment où chaque lambda a été créée.

La solution: Création d'une copie

Pour résoudre ce problème, créez une copie de la variable de boucle dans chaque itération:

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

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

Maintenant, chaque expression de lambda capture une variable copy distincte, résultant en la sortie correcte.

C # 5 et plus tard: foreach et catVs

Dans les versions C # 5 et ultérieures, le comportement de la boucle foreach a changé pour résoudre ce problème. Le compilateur utilise "les variables temporaires d'allocation de fermeture" (CATV) pour créer automatiquement une variable distincte pour chaque itération, éliminant le besoin de copies manuelles. Cette simplification rend le code plus propre et plus lisible. Cependant, l'exemple de boucle while nécessite toujours la copie explicite.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn