18:27

All of the love we left behind watching the flashbacks intertwine. I think our lives have just begun.
Народ, объясните, пожалуйста, замыкания в C#. Каким-нибудь простым человеческим языком. Лямбда-выражения я понимаю, но когда выражение имеет такой вот вид: х += () => Console.Write(i); то я просто теряюсь. Что выполняют эти таинственные скобки? Будет здорово, если объясните на простеньком примере.

@темы: Вопрос, C#

Комментарии
05.06.2013 в 18:49

IDDQD - Команда молодости нашей, команда, без которой мне не жить.
Тут получается примерно следующим образом:
Лямбда-выражение (именно как expression - это важно!) в C# имеет следующий вид:
'(' args ')' '=>' body ';'
где args - это список аргументов, а body - это тело выражение.
Список аргументов может быть:
- пустым;
- перечнем имён аргументов (в этом случае окружающие список аргументов скобки могут быть опущены);
- перечнем имён аргументов с указанием типов.
Типы аргументов должны указываться в случае, когда они не могут быть выведены из контекста использования.

тело выражения - либо простым expression'ом, либо statement'ом. Во втором случае оно должно быть взято в фигурные скобки.
Если тело содержит упоминания локльных переменных из контекста, в котором определяется лямбда, то эти переменные "сохраняются" вместе с лямбда-выражением (получается то самое "замыкание").

В твоём случае:
() => Console.Write(i);
мы имеем лямбду без аргументов (потому что "()" в начале), с expression'ом в качестве тела ("Console.Write(i)"), и которая захватывает одну переменную из внешнего контекста ('i').

Другой пример лямбды:
delegate void Command(Data data);
//...
Command cmd = (string data) => Console.WriteLine("Hello, " + data + "!");

Здесь мы имеем лямбду с одним типизированным аргументом "(string data)" и expression'ом в качестве тела ("Console.WriteLine("Hello, " + data + "!")"), которая ничего не захватывает из внешнего контекста.
Кстати говоря, в этом примере тип аргумента можно было бы опустить, т. к. он может быть выведен из типа делегата, которому присваивается результат. Т. е. запись могла бы быть такой:
Command cmd = data => Console.WriteLine("Hello, " + data + "!");

Подробности - здесь: http://msdn.microsoft.com/en-us/library/bb397687.aspx
05.06.2013 в 19:52

тролль - это не только ценный жир, но и 3-4 легкоусвояемых коммента ежедневно
Благодаря замыканиям, программист способен с помощью конечной программы создать бесконечное количество функций )))
06.06.2013 в 09:55

All of the love we left behind watching the flashbacks intertwine. I think our lives have just begun.
Flex Ferrum, спасибо за объяснение! Не все поняла, но уже яснее стало, буду на основе этих знаний дальше пытаться разбираться)
06.06.2013 в 11:42

IDDQD - Команда молодости нашей, команда, без которой мне не жить.
Не все поняла
А что непонятным осталось?
06.06.2013 в 14:37

All of the love we left behind watching the flashbacks intertwine. I think our lives have just begun.
Flex Ferrum, да, в общем-то, уже ничего - рядом оказался коллега, который показал пару примеров из рабочего проекта и теперь я все полностью поняла) спасибо!