<p>Le compilateur déclare la variable d’une manière qui la rend très sujette à une erreur souvent difficile à trouver et à déboguer, sans produire aucun avantage perceptible.</p>
<p>Votre critique est entièrement justifiée.</p>
<p>Je discute de ce problème en détail ici :</p>
<p><a href="http://ericlippert.com/2009/11/12/closing-over-the-loop-variable-considered-harmful-part-one/">Closing over the loop variable considered harmful</a></p>
<p>Y a-t-il quelque chose que vous pouvez faire avec les boucles foreach de cette façon que vous ne pourriez pas faire si elles étaient compilées avec une variable à portée interne ? Ou est-ce simplement un choix arbitraire qui a été fait avant que les méthodes anonymes et les expressions lambda ne soient disponibles ou courantes, et qui n’a pas été révisé depuis ?</p>
<p>La deuxième option. La spécification C# 1.0 ne précisait en fait pas si la variable de boucle se trouvait à l’intérieur ou à l’extérieur du corps de la boucle, car cela ne faisait aucune différence observable. Lorsque la sémantique des closures a été introduite dans C# 2.0, le choix a été fait de placer la variable de boucle à l’extérieur de la boucle, de manière cohérente avec la boucle “for”.</p>
<p>Je pense qu’il est juste de dire que tout le monde regrette cette décision. C’est l’un des pires pièges en C#, et <strong>nous allons accepter la rupture de compatibilité pour le corriger.</strong> Dans C# 5, la variable de boucle foreach sera logiquement <em>à l’intérieur</em> du corps de la boucle, et par conséquent les closures obtiendront une nouvelle copie à chaque itération.</p>
<p>La boucle <code>for</code> ne sera pas modifiée, et le changement ne sera pas rétro-porté vers les versions précédentes de C#. Vous devriez donc continuer à être prudent lorsque vous utilisez cet idiome.</p>