Ответ
Делегат (Delegate) в C# — это типобезопасный указатель на метод. По сути, это объект, который знает, как вызвать конкретный метод (или группу методов), позволяя передавать методы как параметры, хранить их в переменных и вызывать динамически.
Зачем это нужно? Для реализации паттернов обратного вызова (callback), событийной модели (events) и для повышения гибкости кода, позволяя менять поведение алгоритма, не переписывая его.
Ключевые особенности:
- Типобезопасность: Сигнатура делегата (возвращаемый тип и типы параметров) должна точно совпадать с сигнатурой метода, на который он ссылается.
- Multicast-делегаты: Один делегат может содержать ссылки на несколько методов (
+=для добавления,-=для удаления). При вызове такого делегата методы выполняются последовательно.
Пример объявления и использования пользовательского делегата:
// 1. Объявление типа делегата
public delegate int MathOperation(int a, int b);
public class Calculator
{
// 2. Методы, совместимые с делегатом
public static int Add(int x, int y) => x + y;
public static int Multiply(int x, int y) => x * y;
}
class Program
{
static void Main()
{
// 3. Создание экземпляра делегата и привязка к методу
MathOperation operation = Calculator.Add;
// 4. Вызов метода через делегат
int result = operation(5, 3); // result = 8
Console.WriteLine(result);
// 5. Добавление второго метода (Multicast)
operation += Calculator.Multiply;
// При вызове выполнятся оба метода: Add(5,3) и Multiply(5,3)
// Но возвращено будет значение только от последнего (Multiply -> 15)
result = operation(5, 3); // result = 15
Console.WriteLine(result);
}
}
Встроенные обобщённые делегаты (часто используются вместо объявления своих):
Action<T1, T2, ...>— для методов, которые не возвращают значение (void).Action<string> logAction = message => Console.WriteLine($"[LOG]: {message}"); logAction("Hello");Func<T1, T2, ..., TResult>— для методов, которые возвращают значение.Func<int, int, int> sumFunc = (a, b) => a + b; int sum = sumFunc(10, 20); // sum = 30Predicate<T>— для методов, возвращающихbool(частный случайFunc<T, bool>).
Основные сферы применения:
- События (Events): Основа механизма событий в .NET.
- LINQ: Многие методы расширения LINQ принимают
Func<>илиAction<>как параметры. - Асинхронное программирование: В связке с
async/await. - Реализация паттернов: Например, Стратегия (Strategy), где делегат инкапсулирует алгоритм.
Видео-ответы
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶