Анонимные методы (Руководство по программированию в 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#