Понимаете ли вы замыкания?
От: nikov США http://www.linkedin.com/in/nikov
Дата: 10.12.07 10:37
Оценка: 65 (9)
#Имя: FAQ.cs.closure
Здравствуйте, Аноним, Вы писали:

А>Неужели только я не понимаю, чем первый вариант от второго отличается?


Замыкания реализуются с помощью нескольких compiler-generated классов (в простейших случаях может не понадобиться создавать ни одного класса). Каждый класс соответствует блоку, ограниченному фигурными скобками. Локальные переменные, объявленные внутри блока, становятся полями compiler-generated класса. Важно понимать, что в замыкание захватываются не значения переменных, а сами переменные (значения которых могут измениться к тому моменту, когда они будут использованы). Экземпляр класса, соответствующий внутреннему блоку, хранит ссылку на экземпляр класса, соответствующий внешнему блоку (6.5.3 Implementation example). Каждый раз, когда поток управления входит внутрь блока, создается новый экземпляр соответствующего compiler-generated класса. Этот процесс известен как instantiation of local variables (7.14.4.2 Instantiation of local variables). Когда поток управления покидает блок, экземпляр соответствующего compiler-generated класса может продолжить свое существование, если сохраняются ссылки на делегат, привязанный к такому экземпляру (то есть, делегат, созданный из анонимного метода, объявленного внутри соответствующего блока). Таким образом, даже при наличии только одного потока, одновременно могут существовать несколько экземпляров одного compiler-generated класса, хранящего несколько разных наборов локальных переменных. Если локальные переменные объявлены в различных, вложенных один в другой блоках, то нескольким наборам переменных из внутреннего блока может соответствовать один набор переменных внешнего блока. В приведенных примерах как раз обыгрывается такая ситуация. Переменная-итератор в циклах for и foreach считается объявленной вне блока, являющегося телом цикла, поэтому она инстанциируется всего один раз, независимо от количества итераций. На каждой итерации изменяется значение одного и того же экземпляра этой переменной. Если же мы перекладываем ее значение в другую переменную, объявленную внутри блока, то на каждой итерации создается отдельный экземпляр этой переменной, который не модифицируется при следующих итерациях.

P.S. Ссылки в скобках даны на номера параграфов C# 3.0 Specification Draft.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.