Язык программирования C#9 и платформа .NET5. Страница 235
...}Делегаты могут также "указывать" на методы, которые содержат любое количество параметров
outrefparamspublic delegate string MyOtherDelegate(out bool a, ref bool b, int c);Сигнатура метода
Invoke()Подводя итоги, отметим, что определение типа делегата C# дает в результате запечатанный класс со сгенерированным компилятором методом, в котором типы параметров и возвращаемые типы основаны на объявлении делегата. Базовый шаблон может быть приближенно описан с помощью следующего псевдокода:
// Это лишь псевдокод!public sealed class <i>ИмяДелегата</i> : System.MulticastDelegate{ public <i>возвращаемоеЗначениеДелегата</i> Invoke(<i>всеВходныеRefиOutПараметрыДелегата</i>);}Базовые классы System.MulticastDelegate и System.Delegate
Итак, когда вы строите тип с применением ключевого слова
delegateSystem.MulticastDelegateSystem.MulticastDelegatepublic abstract class MulticastDelegate : Delegate{<b> // Возвращает список методов, на которые "указывает" делегат.</b> public sealed override Delegate[] GetInvocationList();<b> // Перегруженные операции.</b> public static bool operator == (MulticastDelegate d1, MulticastDelegate d2); public static bool operator != (MulticastDelegate d1, MulticastDelegate d2);<b> // Используются внутренне для управления списком методов,</b><b> // поддерживаемых делегатом.</b> private IntPtr _invocationCount; private object _invocationList;}Класс
System.MulticastDelegateSystem.Delegatepublic abstract class Delegate : ICloneable, ISerializable{<b> // Методы для взаимодействия со списком функций.</b> public static Delegate Combine(params Delegate[] delegates); public static Delegate Combine(Delegate a, Delegate b); public static Delegate Remove( Delegate source, Delegate value); public static Delegate RemoveAll( Delegate source, Delegate value);<b> // Перегруженные операции.</b> public static bool operator ==(Delegate d1, Delegate d2); public static bool operator !=(Delegate d1, Delegate d2);<b> // Свойства, открывающие доступ к цели делегата.</b> public MethodInfo Method { get; } public object Target { get; }}Имейте в виду, что вы никогда не сможете напрямую наследовать от таких базовых классов в своем коде (попытка наследования приводит к ошибке на этапе компиляции). Тем не менее, когда вы используете ключевое слово
delegateMulticastDelegate
Пример простейшего делегата
На первый взгляд делегаты могут показаться несколько запутанными. Рассмотрим для начала простой проект консольного приложения (по имени
SimpleDelegateBinaryOp// SimpleMath.csnamespace SimpleDelegate{ // Этот класс содержит методы, на которые // будет указывать BinaryOp. public class SimpleMath { public static int Add(int x, int y) => x + y; public static int Subtract(int x, int y) => x - y; }}// Program.csusing System;using SimpleDelegate;Console.WriteLine("***** Simple Delegate Example *****\n");<b>// Создать объект делегата BinaryOp, который</b><b>// "указывает" на SimpleMath.Add().</b>