Анонимный метод может возвращать значение. Для этой цели служит оператор return, действующий в анонимном методе таким же образом, как и в именованном методе. Как и следовало ожидать, тип возвращаемого значения должен быть совме стим с возвращаемым типом, указываемым в объявлении делегата. В качестве при мера ниже приведен код, выполняющий подсчет с суммированием и возвращающий результат. // Продемонстрировать применение анонимного метода, возвращающего значение. using System; // Этот делегат возвращает значение. delegate int CountIt(int end); class AnonMethDemo3 { static void Main { int result; // Здесь конечное значение для подсчета перелается анонимному методу. // А возвращается сумма подсчитанных чисел. CountIt count = delegate (int end) { int sum = 0; for(int i=0; i <= end; i++) { Console.WriteLine (i); sum += i; } return sum; // возвратить значение из анонимного метода }; result = count(3); Console.WriteLine("Сумма 3 равна " + result); Console.WriteLine; result = count (5); Console.WriteLine("Сумма 5 равна " + result); } }
В этом варианте кода суммарное значение возвращается кодовым блоком, связан ным с экземпляром делегата count. Обратите внимание на то, что оператор return применяется в анонимном методе таким же образом, как и в именованном методе. Ниже приведен результат выполнения данного кода. 0 1 2 3 Сумма 3 равна 6 0 1 2 3 4 5 Сумма 5 равна 15 Применение внешних переменных в анонимных методах
Локальная переменная, в область действия которой входит анонимный метод, на зывается внешней переменной. Такие переменные доступны для использования в ано нимном методе. И в этом случае внешняя переменная считается захваченной. Захвачен ная переменная существует до тех пор, пока захвативший ее делегат не будет собран в "мусор". Поэтому если локальная переменная, которая обычно прекращает свое су ществование после выхода из кодового блока, используется в анонимном методе, то она продолжает существовать до тех пор, пока не будет уничтожен делегат, ссылаю щийся на этот метод.
Захват локальной переменной может привести к неожиданным результатам. В ка честве примера рассмотрим еще один вариант программы подсчета с суммированием чисел. В данном варианте объект CountIt конструируется и возвращается статическим методом Counter. Этот объект использует переменную sum, объявленную в охваты вающей области действия метода Counter, а не самого анонимного метода. Поэто му переменная sum захватывается анонимным методом. Метод Counter вызывается в методе Main для получения объекта CountIt, а следовательно, переменная sum не уничтожается до самого конца программы. // Продемонстрировать применение захваченной переменной. using System; // Этот делегат возвращает значение типа int и принимает аргумент типа int. delegate int CountIt(int end); class VarCapture { static CountIt Counter { int sum = 0; // Здесь подсчитанная сумма сохраняется в переменной sum. CountIt ctObj = delegate (int end) { for(int i=0; i <= end; i++) { Console.WriteLine(i); sum += i; } return sum; }; return ctObj; } static void Main { // Получить результат подсчета. CountIt count = Counter; int result; result = count(3); Console.WriteLine("Сумма 3 равна " + result); Console.WriteLine; result = count (5); Console.WriteLine("Сумма 5 равна " + result); } }
Ниже приведен результат выполнения этой программы. Обратите особое внима ние на суммарное значение. 0 1 2 3 Сумма 3 равна 6 0 1 2 3 4 5 Сумма 5 равна 21
Как видите, подсчет по-прежнему выполняется как обычно. Но обратите внимание на то, что сумма 5 теперь равна 21, а не 15! Дело в том, что переменная sum захваты вается объектом ctObj при его создании в методе Counter. Это означает, что она продолжает существовать вплоть до уничтожения делегата count при "сборке мусо ра" в самом конце программы. Следовательно, ее значение не уничтожается после воз врата из метода Counter или при каждом вызове анонимного метода, когда проис ходит обращение к делегату count в методе Main.
Несмотря на то что применение захваченных переменных может привести к до вольно неожиданным результатам, как в приведенном выше примере, оно все же логически обоснованно. Ведь когда анонимный метод захватывает переменную, она продолжает существовать до тех пор, пока используется захватывающий ее делегат. В противном случае захваченная переменная оказалась бы неопределенной, когда она могла бы потребоваться делегату. Лямбда-выражения