Делегат — форма вказівника на типобезпечну функцію, що використовується Common Language Infrastructure (CLI). Делегати вказують метод для виклику та, за бажанням, об'єкт, для якого буде викликано метод. Делегати використовують, серед іншого, для реалізації зворотних викликів та слухачів подій. Об'єкт делегата інкапсулює посилання на метод. Об'єкт делегата потім можна передати коду, який може викликати метод, на який посилаються, без необхідності знати під час компіляції, який метод буде викликано.

Багатоадресний делегат — це делегат, який вказує на кілька методів.Багатоадресне делегування — це механізм, який забезпечує функціональність для виконання кількох методів. Існує внутрішньо підтримуваний список делегатів, і коли викликається багатоадресний делегат, виконується список делегатів.

У C# делегати часто використовують для реалізації зворотних викликів у подієво-орієнтованому програмуванні. Наприклад, делегат можна використати для позначення методу, який слід викликати, коли користувач натискає на певну кнопку. Делегати дають змогу програмісту повідомляти кілька методів про те, що сталася подія.

Приклад коду на C# Код для оголошення об'єкта типу delegate з назвою SendMessageDelegate, який приймає параметр Message і повертає void:

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

Реалізований метод, який виконується під час виклику делегата:

Код для виклику методу SendMessage, передаючи примірник делегата як аргумент:

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

Змінна-делегат викликає пов'язаний метод, її викликають так:

Змінні-делегати є об'єктами першого класу у формі : їм можна присвоїти будь-який сумісний метод або значення null. Вони зберігають метод та його приймач без будь-яких параметрів:

Об'єкт може бути і тоді його можна не вказувати. Якщо метод статичний, об'єктом має бути не примірником, а сам клас. Метод не може бути абстрактним, але може мати модифікатор new, override або virtual.

Щоб успішно викликати метод з делегатом, сигнатура методу має відповідати з такою ж кількістю параметрів одного й того ж виду (, , ) й однакового типу (включно з типом повернення).

Багатоадресні делегати (C#) Змінна-делегат може містити кілька значень одночасно:

Якщо багатоадресний делегат є функцією або не має параметра , повертається параметр останнього виклику.

Деталі реалізації Хоча внутрішні реалізації можуть відрізнятися, примірники делегатів можна розглядати як кортеж об'єкта, вказівника методу та посилання (можливо, null) на інший делегат. Отже, посилання на один делегат може бути посиланням на кілька делегатів. Коли перший делегат закінчить роботу, якщо його ланцюгове посилання не є null, буде викликано наступний і так далі до закінчення списку. Цей шаблон дає змогу легко масштабувати механізм обробки події — від одного посилання до виклику списку делегатів — і широко використовується в CLI.

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

Правила побудови класів делегатів дуже суворі. Вони надають компіляторам-оптимізаторам значну свободу дій під час оптимізації делегатів, забезпечуючи при цьому безпеку типів.

Див. також Продовження (програмування) Перехоплення (інформатика)

Примітки

Посилання Документація MSDN для делегатів Біла книга Sun про делегати Відповідь Microsoft компанії Sun