Замыкание или ловушка замыкания С#

163
04 июня 2022, 17:50

Не могу понять что делает этот кусок кода. Можете объяснить?

var list = new List<Action>();
for (var i = 0; i < 5; i++)
    list.Add(() => Console.WriteLine(i));
foreach (var func in list)
    func();
Answer 1

Данный код:

  1. Добавляет в список ссылки на вызов анонимной функции (лямбда)
  2. Вызывает сохранённые в списке анонимные функции (лямбды)

"Проблема замыкания" тут в том, что аргументы функции тоже сохраняются по ссылке и при вызове этих функций получается, что каждая вызывается с одним и тем же аргументом - последним значением переменной i после окончания цикла. Как-то так.

Answer 2

Действительно, захват внешних (для лямбда выражения) переменных осуществляется «по ссылке», это означает, что переменная i исчезает из стека и становится полем специально сгенерированного класса, в который затем помещается и тело анонимного метода.

Интересно отметить, что начиная с С# 5 вот такое выражение (ваш код c использованием foreach):

var list = new List<Action>();
foreach (var i in Enumerable.Range(1, 5))
    list.Add(() => Console.WriteLine(i));
foreach (var func in list)
    func();

Выдаст предсказуемый результат

1
2
3

Начиная с пятой версии языка переменная в цикле foreach создаётся заново при каждой итерации. Следовательно для того, чтобы получить результат 1 2 3 в предыдущих языках с foreach или в любой версии с for нужно просто создать переменную внутри цикла:

var list = new List<Action>();
for (var i = 0; i < 5; i++)
{
    var temp = i;
    list.Add(() => Console.WriteLine(temp));
}
foreach (var func in list)
    func();
READ ALSO
как сохранить данные в localstorage

как сохранить данные в localstorage

В textarea записываются данные

143
как скрыть картинку и вывести другую в fancybox?

как скрыть картинку и вывести другую в fancybox?

Не получается скрыть картинку в fancybox, документации не нашел, documentgetElementById(wheel)

168
Редактирование данных пользователя React

Редактирование данных пользователя React

Помогите с кейсом,нужно сделать post запрос получить данные пользователя fio,inn,password и записать их в стейт потом отобразить в input и что бы администратор...

181
Хочу переделать скрипт добавляющий определенные символы

Хочу переделать скрипт добавляющий определенные символы

Делаю скрипт на jquery, который должен добавлять к определенному символу/словосочетанию/цифрам также определенные символы/словосочетания/цифрыНапример...

176