This is a mirror of official site: http://jasper-net.blogspot.com/

Замыкания в языке C#

| Monday, September 13, 2010
Введение

В статье рассказывается внутренняя реализация замыканий (closure) в языке C# и описываются основные подводные камни, с которыми может столкнуться разработчик в своей повседневной деятельности.

C#, замыкания, функциональное программирование

Возможно, вы никогда не слышали о таком понятии как замыкания (closure), или слышали, но все эти функциональные штучки показались вам настолько сложным, что вы решили отложить их изучение до тех славных времен, когда компиляторы будут писать программы за вас, или хотя бы в компьютерах будет предусмотрен отдельный процессор для сборщика мусора. Но, независимо от ваших знаний и представлений о замыканиях, можно сказать с уверенностью, что вы, будучи программистом C#, не раз сталкивались с этим понятием в своей повседневной деятельности (конечно, я рассчитываю, что вы не застряли в прошлом и перешли хотя бы на C# 2.0), поэтому знать, что же это такое, будет не лишним.

Основные определения

Давайте посмотрим на некоторые популярные определения термина “замыкание”:

Замыкание (англ. closure) — это процедура, которая ссылается на свободные переменные в своём лексическом контексте. Замыкание, так же как и экземпляр объекта, есть способ представления функциональности и данных, связанных и упакованных вместе.

Замыкания (closures) представляют собой фрагменты (блоки) кода, который можно использовать в качестве аргументов функций и методов.

В процессе понимания таких определений неподготовленный читатель вполне может вывихнуть свой мозг и потерять охоту к изучению этого понятия навсегда. Но, на самом деле, все не так страшно. Если говорить проще и не столь формально, да еще в контексте языка C#, то идея замыканий состоит в доступе анонимного метода не только к переданным параметрам, но и к внешнему окружению (если пока что не совсем ясно, что такое “внешнее окружение”, то это станет понятно позднее).

Прежде чем мы перейдем к примерам, нужно дать еще несколько определений, необходимых для понимания механизма замыканий в языке C#.

Внешняя переменная (outer variable) – это локальная переменная или параметр (за исключением ref- и out-параметров), доступные внутри метода, в котором объявлен анонимный метод (ключевое слово this можно также рассматривать в качестве локальной переменной).

Захваченная внешняя переменная (captured outer variable) или просто захваченная переменная (captured variable) – это внешняя переменная, используемая внутри анонимного метода.

Пример замыканий в языке C#

Чтобы было несколько проще переварить все эти термины, приведу простой пример. Предположим, вам нужно выполнить некоторую операцию асинхронно, и вместо того, чтобы создавать новый поток вручную или использовать асинхронный вызов делегатов, вы решили воспользоваться помощью класса ThreadPool.

void EnclosingMethod(bool outerVariable1, //1
 ref int nonOuterVariable) //2
{
 int outerVariable2 = 10; //3
 string capturedVariable = "captured"; //4

 if (outerVariable2 % 2 == 0)
 {
   int normalLocalVariable = 5; //5
   Console.WriteLine("Normal local variable: {0}", normalLocalVariable);
 }

 WaitCallback d =
   delegate(object o)
   {
     int anonymousMethodLocalVariable = 12; //6
     Console.WriteLine("Captured variable is {0}", capturedVariable);
   };

 ThreadPool.QueueUserWorkItem(d, null);
}


Read more: RSDN

Posted via email from .NET Info

0 comments: