Mit Visual Studio 2013 versuche ich, die in Eric Lippert Blogeintrag "Closing over the loop variable considered harmful" genannten Gotcha reproduzieren.Reproduzieren der "Close über die Variable einer Foreach" Gotcha
In den Projekteigenschaften habe ich "C# 3.0" als Sprachversion gewählt (Build> Erweitert ...). Außerdem habe ich ".NET Framework 3.5" als Zielframework ausgewählt, als ob ich denke, dass dies nicht notwendig sein sollte, da dies ausschließlich die Sprache betrifft.
Rennen seinen Code:
using System;
using System.Collections.Generic;
namespace Project1
{
class Class1
{
public static void Main(string[] args)
{
var values = new List<int>() { 100, 110, 120 };
var funcs = new List<Func<int>>();
foreach (var v in values)
{
funcs.Add(() => v);
}
foreach (var f in funcs)
Console.WriteLine(f());
}
}
}
Erwartete Ausgabe:
120 120 120
tatsächliche Ausgang:
100 110 120
Wie Eric Lippert himself in "Is there a reason for C#'s reuse of the variable in a foreach?" beantwortet:
Die
for
-Schleife wird nicht geändert, und die Änderung wird nicht auf vorherige Versionen von C# zurück portiert. Sie sollten daher weiterhin vorsichtig sein, wenn Sie dieses Idiom verwenden.
Was mache ich falsch?
Wann bricht Code tatsächlich ab? Ich schätze, wenn der Code auf einen Fehler im alten Compiler stützte, der dann behoben wird oder wenn der neue Compiler einen Fehler einführt. Gibt es andere Szenarien, in denen dies nützlich sein könnte? – xehpuk
@xehpuk: Ich bin mir nicht sicher, ob ich deine Frage verstehe. Es ist sicherlich der Fall, dass Code, der sich auf behobene Compiler-Fehler stützte, unabhängig vom Wert des langversion-Schalters bricht. Das Compiler-Team ist sehr bemüht, die Rückwärtskompatibilität bei der Behebung von Fehlern beizubehalten, dies ist jedoch nicht immer möglich. –
Sie haben Recht, es ist immer noch derselbe Compiler. Der Anwendungsfall besteht also im Grunde darin, dass ein Projektmitglied eine neuere Version des Compilers hat, die älteren aber nicht einfach verwenden kann (weil er z. B. eine neuere Version von VS verwendet, die aus irgendeinem Grund diese Option nicht hat). – xehpuk