Was Sie sehen, ist das Ergebnis von zwei verschiedenen Anwendungen von foreach
. Das Verhalten wurde in VS 2012 geändert. Siehe this article.
Der Unterschied zwischen den beiden beinhaltet den Umfang und die Lebensdauer der d
Variable in der foreach
Schleife. Vor VS 2012 gab es nur eine d
Variable, was bedeutet, dass Sie zwei Kopien eines Verschlusses erstellen (s => (s % d == 0))
), die beide die selbed
referenzieren. Nachdem die Schleife ausgewertet wurde, ist d
10. Wenn Sie die Abfrage ausführen, indem Sie .Distinct().Count()
aufrufen, sehen beide Schließungen einen Wert von 10 für d
. Aus diesem Grunde ist die Anzahl 1 auf VS 2010
VS 2012 erzeugt eine andere Variable für jede Iteration 1, so dass jede Schließung sieht eine verschiedene Instanz des d
Variable, die eine, die zu diesem bestimmten entspricht Iteration. Diese
ist in etwa der Code, der VS 2010 erzeugt:
int d;
for (int _index = 0; _index < divisors.Length; ++_index) {
d = divisors[_index];
m = m.Concat(nums.Where(s => (s % d == 0)));
}
Und das ist ungefähr das, was VS 2012 erzeugt:
for (int _index = 0; _index < divisors.Length; ++_index) {
int d = divisors[_index];
m = m.Concat(nums.Where(s => (s % d == 0)));
}
Der Unterschied zwischen diesen beiden sollte leicht ersichtlich sein.
Wenn Sie möchten, egal das gleiche Verhalten erhalten, die VS-Version, dann immer Ihre Iterationsvariable kopieren:
foreach (int d in divisors)
{
var copy = d;
m = m.Concat(nums.Where(s => (s % copy == 0)));
}
Technisch nur, wenn die Iterationsvariable referenziert wird in ein Verschluss. Ist dies nicht der Fall, muss keine Kopie erstellt werden, da dies ohnehin nur die Semantik des Abschlusses betrifft.
Nachschärfwarnung: Zugang zu modifiziertem Verschluss –