Какие виды делегатов существуют в C#?

«Какие виды делегатов существуют в C#?» — вопрос из категории C# Core, который задают на 47% собеседований C# Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

В C# делегаты — это типобезопасные указатели на методы. Основные виды:

  1. Пользовательские делегаты (обычные) — объявляются с ключевым словом delegate. Используются реже, так как в большинстве случаев их заменяют Action и Func.

    delegate int StringToIntConverter(string input);
  2. Action — предопределённый обобщённый делегат для методов, которые не возвращают значение (возвращают void). Может принимать от 0 до 16 параметров.

    Action<string> logAction = (message) => Console.WriteLine($"[LOG]: {message}");
    Action<int, int> sumAction = (a, b) => Console.WriteLine(a + b);
  3. Func — предопределённый обобщённый делегат для методов, которые возвращают значение. Последний параметр типа всегда указывает на возвращаемый тип.

    Func<int, int, int> addFunc = (a, b) => a + b;
    Func<string, bool> isNotEmptyFunc = (str) => !string.IsNullOrEmpty(str);
  4. Predicate<T> — специализированный делегат для проверки условия. Возвращает bool. По сути, это аналог Func<T, bool>, но с более ясным намерением в коде.

    Predicate<int> isEvenPredicate = (number) => number % 2 == 0;
    // Эквивалентно: Func<int, bool> isEvenFunc = ...
  5. EventHandler и EventHandler<TEventArgs> — стандартные делегаты для реализации событийной модели.

    public event EventHandler SomethingHappened;
    public event EventHandler<FileLoadedEventArgs> FileLoaded;

Почему это важно: Action и Func устраняют необходимость вручную объявлять множество делегатов, делая код чище и более унифицированным. Все делегаты в C# являются мультикаст-делегатами — они могут содержать ссылки на несколько методов и вызывать их по цепочке.

Action multiAction = () => Console.Write("Hello, ");
multiAction += () => Console.WriteLine("World!");
multiAction(); // Выведет: "Hello, World!"