Ответ
Делегат в C# — это безопасный тип указателя на метод, который определяет сигнатуру (возвращаемый тип и параметры). С точки зрения системы типов, делегат является ссылочным типом (class), производным от System.MulticastDelegate.
Суть делегата: Он позволяет инкапсулировать метод в объект, который можно передавать как параметр, хранить в поле или вызывать.
Пример: создание и использование пользовательского делегата
// 1. Объявление типа делегата
public delegate int Processor(int x, int y);
// 2. Методы, совместимые с сигнатурой делегата
static int Add(int a, int b) => a + b;
static int Multiply(int a, int b) => a * b;
// 3. Создание экземпляра делегата и вызов
Processor operation = Add;
int result = operation(5, 3); // result = 8
// 4. Multicast: делегат может ссылаться на несколько методов
operation += Multiply;
result = operation(5, 3); // Последовательно вызовет Add(5,3), затем Multiply(5,3).
// В result будет записан результат последнего метода (15).
Почему делегаты важны? Они — основа событийной модели .NET и LINQ.
Современные встроенные обобщённые делегаты (чаще используются на практике):
Action— для методов, которые не возвращают значение (void).Action<string> logger = message => Console.WriteLine($"[LOG]: {message}"); logger("App started");Func— для методов, возвращающих значение.Func<int, int, int> calculator = (x, y) => x + y; int sum = calculator(10, 20); // sum = 30Predicate<T>— частный случайFunc<T, bool>, используется для проверки условий.
Ключевой паттерн на делегатах — Callback:
public void ProcessData(List<int> data, Action<int> progressCallback)
{
for (int i = 0; i < data.Count; i++)
{
// ... обработка ...
progressCallback?.Invoke(i + 1); // Вызов callback для обновления UI
}
}
// Использование
ProcessData(myList, progress => Console.WriteLine($"Обработано: {progress} элементов"));