В старых версиях компиляторов приведённый код превращался в следующую конструкцию:
publicvoidRun(){var actions =newList<Action>();DisplayClass c1 =newDisplayClass();foreach (int i inEnumerable.Range(1,3)) { с1.i= i;list.Add(c1.Action); }foreach (Action action in list)action();}privatesealedclassDisplayClass{publicint i;publicvoidAction() {Console.WriteLine(i); }}
Таким образом, все три элемента списка на самом деле являются одним и тем же делегатом, поэтому в консоли мы увидим три одинаковых значения, равных последнему значению i.
В современных версиях компиляторов произошли изменения, новый вариант кода:
publicvoidRun(){var actions =newList<Action>();foreach (int i inEnumerable.Range(1,3)) {DisplayClass c1 =newDisplayClass(); с1.i= i;list.Add(c1.Action); }foreach (Action action in list)action();}privatesealedclassDisplayClass{publicint i;publicvoidAction() {Console.WriteLine(i); }}
Теперь каждый элемент списка ссылается на собственный делегат, так что все полученные значения будут разными.