Проблема в том, что вы захватываете переменную цикла.Все ваши делегаты захватывают одну и ту же переменную, поэтому они всегда будут видеть последнее значение a
... которое будет values.Length + 1
к тому времени, когда вы выполняете делегаты, в ваших случаях использования.Вместо этого вы можете просто скопировать его:
for (int a = 0; a < values.Length; a++)
{
int copy = a;
yield return () => Values[copy];
}
В качестве альтернативы (и предпочтительно ИМО) используйте цикл foreach
, который в настоящее время требует того же обходного пути:
foreach (int value in values)
{
int copy = value;
yield return () => copy;
}
Или еще лучше:
return values.Select(x => (Func<int>)(() => x));
Или:
Func<int, Func<int>> projection = x => () => x;
return values.Select(projection);
См. Сообщение в блоге Эрика Липперта "Закрытие переменной цикла, считающейся вредной" для получения дополнительной информации.Обратите внимание, что поведение foreach
вполне может измениться для C # 4.5.