Делегат (CLI)

редактировать

A делегат - это форма type-sa fe указатель на функцию, используемый Common Language Infrastructure (CLI). Делегаты указывают метод для вызова и, необязательно, объект для вызова метода. Среди прочего, делегаты используются для реализации обратных вызовов и прослушивателей событий. Объект делегата инкапсулирует ссылку на метод. Затем объект делегата может быть передан в код, который может вызывать метод, на который указывает ссылка, без необходимости знать во время компиляции, какой метод будет вызван.

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

В C # делегаты часто используются для реализации обратных вызовов в программировании, управляемом событиями. Например, делегат может использоваться, чтобы указать, какой метод должен быть вызван, когда пользователь нажимает какую-либо кнопку. Делегаты позволяют программисту уведомлять несколько методов о том, что произошло событие.

Содержание
  • 1 Пример кода C #
    • 1.1 Делегаты (C #)
    • 1.2 Многоадресные делегаты (C #)
  • 2 Технические детали реализации
  • 3 Производительность
  • 4 См. Также
  • 5 Ссылки
  • 6 Внешние ссылки
Пример кода C #

Код для объявления типа делегатас именем SendMessageDelegate, который принимает сообщение Messageв качестве параметра и возвращает void:

delegate void SendMessageDelegate (сообщение сообщения);

Код для определения метода, который принимает созданный экземпляр делегата в качестве аргумента:

void SendMessage (SendMessageDelegate sendMessageDelegateReference) {// Вызов делегата и любых других связанных делегатов синхронно. sendMessageDelegateReference (новое сообщение («привет, это образец сообщения»)); }

Реализованный метод, который запускается при вызове делегата:

void HandleSendMessage (Message message) {// Реализация для классов Sender и Message не имеет отношения к этому примеру. Sender.Send (сообщение); }

Код для вызова метода SendMessage с передачей созданного экземпляра делегата в качестве аргумента:

SendMessage (новый SendMessageDelegate (HandleSendMessage));

Делегаты (C #)

делегат void Notifier (отправитель строки); // Обычная подпись метода с ключевым словом delegate Notifier greetMe; // Делегируемая переменная void HowAreYou (отправитель строки) {Console.WriteLine ("Как дела," + отправитель + '?'); } greetMe = новый уведомитель (HowAreYou);

Переменная делегата вызывает связанный метод и вызывается следующим образом:

greetMe ("Антон"); // Вызывает HowAreYou ("Антон") и выводит "Как дела, Антон?"

Переменные-делегаты - это объекты первого класса формы new DelegateType (obj.Method), которые могут быть присвоены любому методу сопоставления или значению null. Они хранят метод и его получатель без каких-либо параметров:

new DelegateType (funnyObj.HowAreYou);

Объект funnyObjможет быть этими опускаться. Если метод static, это должен быть не объект (также называемый экземпляром в других языках), а сам класс. Это не должно быть abstract, но может быть new, overrideили virtual.

Для успешного вызова метода с делегатом подпись метода должен соответствовать DelegateTypeс таким же количеством параметров одного типа (ref, out, value) с тем же типом (включая возвращаемый тип).

Делегаты многоадресной рассылки (C #)

Переменная делегата может одновременно содержать несколько значений:

void HowAreYou (отправитель строки) {Console.WriteLine ("How are you," + отправитель + '?'); } void HowAreYouToday (отправитель строки) {Console.WriteLine ("Как дела сегодня" + отправитель + '?'); } Уведомитель greetMe; greetMe = HowAreYou; greetMe + = HowAreYouToday; greetMe ("Леонардо"); // "Как дела, Леонардо?" // "Как дела, Леонардо?" greetMe - = HowAreYou; greetMe ("Перейра"); // "Как дела, Перейра?"

Если делегат многоадресной рассылки является функцией или не имеет параметра out, возвращается параметр последнего вызова.

Детали технической реализации

Хотя внутренний реализации могут отличаться, экземпляры делегата можно рассматривать как кортеж объекта и метод указатель и ссылка (возможно, пустая) на другой делегат. Следовательно, ссылка на одного делегата может быть ссылкой на несколько делегатов. Когда первый делегат завершит работу, если его ссылка на цепочку не равна нулю, будет вызываться следующий и так далее, пока список не будет завершен. Этот шаблон позволяет событию легко масштабировать накладные расходы от одиночной ссылки до отправки списку делегатов и широко используется в CLI.

Производительность

Производительность делегатов раньше была намного ниже, чем при вызове метода виртуального или интерфейса (в 6-8 раз медленнее в тестах Microsoft 2003), но, начиная с .NET 2.0 CLR в 2005 году, это примерно то же самое, что и вызовы интерфейса. Это означает, что существуют небольшие дополнительные накладные расходы по сравнению с прямым вызовом методов.

Существуют очень строгие правила построения классов делегатов. Эти правила предоставляют оптимизирующим компиляторам большую свободу действий при оптимизации делегатов, обеспечивая при этом безопасность типов.

См. Также
Ссылки
Внешние ссылки
Последняя правка сделана 2021-05-17 12:03:21
Содержание доступно по лицензии CC BY-SA 3.0 (если не указано иное).
Обратная связь: support@alphapedia.ru
Соглашение
О проекте