Анонимные методы

59

Метод, на который ссылается делегат, нередко используется только для этой цели. Иными словами, единственным основанием для существования метода служит то обстоятельство, что он может быть вызван посредством делегата, но сам он не вызывается вообще. В подобных случаях можно воспользоваться анонимной функцией, чтобы не создавать отдельный метод. Анонимная функция, по существу, представляет собой безымянный кодовый блок, передаваемый конструктору делегата. Преимущество анонимной функции состоит, в частности, в ее простоте. Благодаря ей отпадает необходимость объявлять отдельный метод, единственное назначение которого состоит в том, что он передается делегату.

Начиная с версии 3.0, в C# предусмотрены две разновидности анонимных функций - анонимные методы и лямбда-выражения:

Анонимные функции C#

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

Анонимный метод — один из способов создания безымянного блока кода, связанного с конкретным экземпляром делегата. Для создания анонимного метода достаточно указать кодовый блок после ключевого слова delegate. Покажем, как это делается, на конкретном примере:

using System;
using System.Collections.Generic;

namespace ConsoleApplication1
{
    delegate int Sum(int number);

    class Program
    {
        static Sum SomeVar()
        {
            int result = 0;

            // Вызов анонимного метода
            Sum del = delegate (int number)
            {
                for (int i = 0; i <= number; i++)
                    result += i;
                return result;
            };
            return del;
        }

        static void Main()
        {
            Sum del1 = SomeVar();

            for (int i = 1; i <= 5; i++)
            {
                Console.WriteLine("Cумма {0} равна: {1}",i,del1(i));
            }

            Console.ReadLine();
        }
    }
}
Анонимные методы

Обратите внимание на получившийся результат. Локальная переменная, в область действия которой входит анонимный метод, называется внешней переменной. Такие переменные доступны для использования в анонимном методе. И в этом случае внешняя переменная считается захваченной. Захваченная переменная существует до тех пор, пока захвативший ее делегат не будет собран в "мусор". Поэтому если локальная переменная, которая обычно прекращает свое существование после выхода из кодового блока, используется в анонимном методе, то она продолжает существовать до тех пор, пока не будет уничтожен делегат, ссылающийся на этот метод.

Захват локальной переменной может привести к неожиданным результатам, как в приведенном выше примере, где локальная переменная result не обнуляется после каждого вызова анонимного метода. В результате получается необычный результат суммы чисел.

Пройди тесты
Лучший чат для C# программистов