Делегаты (Руководство по программированию на C#)
Делегат — это тип, который представляет ссылки на методы с определенным списком параметров и типом возвращаемого значения. При создании экземпляра делегата этот экземпляр можно связать с любым методом с совместимой сигнатурой и типом возвращаемого значения. Метод можно вызвать (активировать) с помощью экземпляра делегата.
Делегаты используются для передачи методов в качестве аргументов к другим методам. Обработчики событий — это ничто иное, как методы, вызываемые с помощью делегатов. При создании пользовательского метода класс (например, элемент управления Windows) может вызывать этот метод при появлении определенного события. В следующем примере показано объявление делегата:
public delegate int PerformCalculation(int x, int y);
Делегату можно назначить любой метод из любого доступного класса или структуры, соответствующей типу делегата. Этот метод должен быть статическим методом или методом экземпляра. Такая гибкость позволяет программно изменять вызовы метода, а также включать новый код в существующие классы.
Примечание
В контексте перегрузки метода его сигнатура не содержит возвращаемое значение. Однако в контексте делегатов сигнатура метода содержит возвращаемое значение. Другими словами, метод должен иметь тот же возвращаемый тип, что и делегат.
Благодаря возможности ссылаться на метод как на параметр делегаты идеально подходят для определения методов обратного вызова. Можно написать метод, сравнивающий два объекта в приложении. Этот метод можно использовать в делегате для алгоритма сортировки. Поскольку код сравнения отделен от библиотеки, метод сортировки может быть более общим.
В C# 9 для похожих сценариев, где требуется больший контроль над соглашением о вызовах, были добавлены указатели на функции. Код, связанный с делегатом, вызывается с помощью виртуального метода, добавленного к типу делегата. Используя указатели функций, можно указать другие соглашения.
Общие сведения о делегатах
Делегаты имеют следующие свойства.
- Делегаты подобны указателям на функции в C++, но являются полностью объектно-ориентированными и, в отличие от указателей C++ на функции-члены, инкапсулируют экземпляр объекта вместе с методом.
- Делегаты допускают передачу методов в качестве параметров.
- Делегаты можно использовать для определения методов обратного вызова.
- Делегаты можно связывать друг с другом; например, при появлении одного события можно вызывать несколько методов.
- Точное соответствие методов типу делегата не требуется. Дополнительные сведения см. в разделе Использование вариативности в делегатах.
- Для краткой записи встроенных блоков кода введены лямбда-выражения. В результате компиляции лямбда-выражений (в определенном контексте) получаются типы делегатов. Дополнительные сведения о лямбда-выражениях см. в разделе Лямбда-выражения.
В этом разделе
- Использование делегатов
- Использование делегатов вместо интерфейсов (руководство по программированию на C#)
- Делегаты с именованными методами и делегаты с анонимными методами
- Использование расхождения в делегатах
- Практическое руководство. Объединение делегатов (многоадресные делегаты)
- Практическое руководство. Объявление, создание и использование делегата
Спецификация языка C#
Дополнительные сведения см. в разделе Делегаты в Спецификации языка C#. Спецификация языка является предписывающим источником информации о синтаксисе и использовании языка C#.
Главы в популярных книгах
- Делегаты, события и лямбда-выражения в справочном руководстве по C# 3.0, третье издание. Более 250 решений для программистов на C# 3.0
- Делегаты и события в статье Изучение C# 3.0: основные понятия C# 3.0