Вы фиксируете переменную цикла в своем лямбда-выражении, что означает, что когда делегат наконец вызывается, он видит окончательное значение переменной цикла.
Простое исправление:
foreach (int value in values)
{
int copy = value;
actions.Add(() => copy * copy);
}
Таким образом, вы получаете новую переменную copy
на каждой итерации цикла, поэтому каждое выражение делегата будет захватывать разные переменные, и на них не влияет переменная цикла (value
)меняется со временем.
Эрик Липперт объясняет это хорошо в «Закрытие переменной цикла, считающейся вредной» (и часть вторая ).
В основномэто «гоча» в C #, на который рано или поздно почти все влюбляются.