Глава завершается исследованием =>) можно указывать блок операторов кода (и подлежащие передаче им параметры) везде, где требуется строго типизированный делегат. Как будет показано, лямбда-выражение — не более чем замаскированный анонимный метод и является упрощенным подходом к работе с делегатами. Вдобавок та же самая операция (в .NEТ Framework 4.6 и последующих версиях) может применяться для реализации метода или свойства, содержащего единственный оператор, посредством лаконичного синтаксиса.
Понятие типа делегата
Прежде чем формально определить делегаты, давайте ненадолго оглянемся назад. Исторически сложилось так, что в API-интерфейсе Windows часто использовались указатели на функции в стиле С для создания сущностей под названием
В .NET и .NET Core обратные вызовы выполняются в безопасной в отношении типов объектно-ориентированной манере с использованием
В частности, делегат поддерживает три важных порции информации:
•
•
•
На заметку! Делегаты .NET Core могут указывать либо на статические методы, либо на методы экземпляра.
После того как делегат создан и снабжен необходимой информацией, он может во время выполнения динамически вызывать метод или методы, на которые указывает.
Определение типа делегата в C#
Для определения типа делегата в языке C# применяется ключевое слово delegate. Имя типа делегата может быть любым желаемым. Однако сигнатура определяемого делегата должна совпадать с сигнатурой метода или методов, на которые он будет указывать. Например, приведенный ниже тип делегата (по имени BinaryOp) может указывать на любой метод, который возвращает целое число и принимает два целых числа в качестве входных параметров (позже в главе вы самостоятельно построите такой делегат, а пока он представлен лишь кратко):
// Этот делегат может указывать на любой метод, который принимает
// два целочисленных значения и возвращает целочисленное значение.
public delegate int BinaryOp(int x, int y);
Когда компилятор C# обрабатывает тип делегата, он автоматически генерирует запечатанный (sealed) класс, производный от System.MulticastDelegate. Этот класс (в сочетании со своим базовым классом System.Delegate) предоставляет необходимую инфраструктуру для делегата, которая позволяет хранить список методов, подлежащих вызову в будущем. Например, если вы изучите делегат BinaryOp с помощью утилиты ildasm.exe, то обнаружите показанные ниже детали (вскоре вы построите полный пример):
// -------------------------------------------------------
// TypDefName: SimpleDelegate.BinaryOp
// Extends : System.MulticastDelegate
// Method #1
// -------------------------------------------------------
// MethodName: .ctor
// ReturnType: Void
// 2 Arguments
// Argument #1: Object
// Argument #2: I
// Method #2
// -------------------------------------------------------
// MethodName: Invoke
// ReturnType: I4
// 2 Arguments
// Argument #1: I4
// Argument #2: I4
// 2 Parameters