Compréhension approfondie de la capture de variables dans les fermetures C# : types de valeur et types de référence
La capture de variables au sein d'une fermeture permet d'accéder à des variables externes dans le cadre de la fermeture. Cependant, les mécanismes et les complexités qui la sous-tendent sont souvent insaisissables. Cet article approfondit les détails de ce processus, en analysant les types de valeur, les types de référence et la boxe.
Capture variable : le mécanisme en coulisses
La capture de variables locales fait plus que simplement les référencer ; le compilateur crée une classe interne pour stocker ces variables. Chaque variable capturée est placée dans un champ de cette classe et sa valeur est copiée lors de la création de la fermeture.
Types de valeur et types de référence
Quel que soit le type de variable, ce qui est capturé est la variable elle-même, et non sa valeur. Pour les types valeur, la valeur réelle est copiée et stockée dans la classe interne. Les types de référence, en revanche, ne sont pas copiés, mais une référence à un emplacement de mémoire partagée est conservée.
Boxe et capture variable
La conversion d'un type valeur en son homologue objet (boxing) ne se produit pas lors de la capture de variable. La valeur capturée est conservée dans la classe interne dans son type de valeur d'origine.
Exemple de description
Pour illustrer ce processus, considérons l'expression lambda suivante capturant une valeur aléatoire :
<code class="language-csharp">Action action = () => { Console.WriteLine(counter); counter++; };</code>
L'extension du compilateur crée une classe ActionHelper interne :
<code class="language-csharp">class ActionHelper { public int counter; public void DoAction() { Console.WriteLine(counter); counter++; } }</code>
L'expression lambda est convertie en un délégué dont la référence cible pointe vers une instance d'ActionHelper. La valeur initiale du compteur est stockée dans le champ du compteur d'ActionHelper. Les appels ultérieurs à l’action modifieront la valeur du compteur partagé.
Fermetures multiples, variables partagées
Lorsque vous traitez plusieurs fermetures partageant une variable, chaque fermeture conserve une référence au même champ de classe interne. Cela permet à plusieurs fermetures d'accéder et de modifier la même valeur, comme indiqué dans le code suivant :
<code class="language-csharp">Action show = () => Console.WriteLine(counter); Action increment = () => counter++;</code>
Dans ce cas, les deux expressions lambda partagent le même champ compteur dans la classe interne.
Conclusion
Comprendre la capture des variables dans les fermetures est essentiel pour utiliser efficacement les fermetures. Le compilateur créera soigneusement des classes internes pour encapsuler les variables capturées, garantissant qu'elles sont disponibles pendant toute la durée de vie de la fermeture. Qu'il s'agisse d'un type valeur ou d'un type référence, ce qui est capturé est la variable réelle, et non la valeur de référence ou encadrée. Ces connaissances permettent aux développeurs d'exploiter habilement la puissance des fermetures.
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!