Поделиться через


Анонимные методы (Руководство по программированию в C#)

Именованные методы были единственным способом объявления делегата в версиях C#, предшествующих версии 2.0. Анонимные методы были представлены в C# 2.0, а в версиях C# 3.0 и более поздних лямбда-выражения заменяют эти методы и являются предпочтительным способом написания встроенного кода. Однако сведения об анонимных методах, представленные в данном разделе, применяются и к лямбда-выражениям. Существует только один случай, в котором функциональность анонимного метода отсутствует в лямбда-выражениях. Анонимные методы позволяют отказаться от использования списка параметров. Это означает, что анонимный метод может быть преобразован в делегаты с различными сигнатурами. Это невозможно в ситуации с лямбда-выражениями. Дополнительные сведения именно о лямбда-выражениях см. в разделе Лямбда-выражения (Руководство по программированию в C#).

Создание анонимных методов является, по существу, способом передачи блока кода в качестве параметра делегата. Два примера:

// Create a handler for a click event.
button1.Click += delegate(System.Object o, System.EventArgs e)
                   { System.Windows.Forms.MessageBox.Show("Click!"); };
// Create a delegate.
delegate void Del(int x);

// Instantiate the delegate using an anonymous method.
Del d = delegate(int k) { /* ... */ };

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

Например, указание блока кода вместо делегата может быть целесообразно в ситуации, когда создание метода может показаться ненужным действием. Хорошим примером является запуск нового потока. Этот класс создает поток и содержит код, выполняемый потоком без создания дополнительного метода для его делегата.

void StartThread()
{
    System.Threading.Thread t1 = new System.Threading.Thread
      (delegate()
            {
                System.Console.Write("Hello, ");
                System.Console.WriteLine("World!");
            });
    t1.Start();
}

Заметки

Областью действия параметров анонимного метода является блок анонимного метода.

Если целевой объект находится вне блока, то наличие оператора перехода, например goto, break или continue, в блоке анонимного метода будет ошибкой. Если целевой объект находится внутри блока, то наличие оператора перехода, например goto, break или continue, вне блока анонимного метода также будет ошибкой.

Локальные переменные и параметры, область действия которых содержит объявление анонимного метода, называются внешними переменными анонимного метода. Например, в следующем сегменте кода n является внешней переменной.

int n = 0;
Del d = delegate() { System.Console.WriteLine("Copy #:{0}", ++n); };

В отличие от локальных переменных, жизненный цикл перехваченной переменной продолжается до тех пор, пока делегаты, ссылающиеся на анонимные методы, могут выполнять сборку мусора. Ссылка на переменную n перехватывается во время создания делегата.

Анонимный метод не может обращаться к параметрам ref или out внешней области действия.

В блоке анонимного метода нельзя получить доступ ни к одному небезопасному коду.

Анонимные методы не разрешены с левой стороны оператора is.

Пример

В следующем примере представлено два способа создания делегата.

  • Связывание делегата с анонимным методом.

  • Связывание делегата с именованным методом (DoWork).

В каждом случае при вызове делегата отображается сообщение.

// Declare a delegate.
delegate void Printer(string s);

class TestClass
{
    static void Main()
    {
        // Instatiate the delegate type using an anonymous method.
        Printer p = delegate(string j)
        {
            System.Console.WriteLine(j);
        };

        // Results from the anonymous delegate call.
        p("The delegate using the anonymous method is called.");

        // The delegate instantiation using a named method "DoWork".
        p = new Printer(TestClass.DoWork);

        // Results from the old style delegate call.
        p("The delegate using the named method is called.");
    }

    // The method associated with the named delegate.
    static void DoWork(string k)
    {
        System.Console.WriteLine(k);
    }
}
/* Output:
    The delegate using the anonymous method is called.
    The delegate using the named method is called.
*/

См. также

Ссылки

Делегаты (Руководство по программированию на C#)

Лямбда-выражения (Руководство по программированию в C#)

Небезопасный код и указатели (Руководство по программированию в C#)

Методы (Руководство по программированию на C#)

Делегаты с именованными методами и делегаты с анонимными методами (Руководство по программированию в C#)

Основные понятия

Руководство по программированию на C#

Другие ресурсы

Справочник по C#