Что такое делегаты в C#?
Содержание
Делегаты - это указатель функции безопасного типа. Он содержит ссылку на функцию.
Подпись делегатов соответствует сигнатуре функции, которая указывает на то, что вы получите ошибку компиляции.
Делегаты являются указателями типов, потому что они указывают на функцию и содержат подпись функции.
Как объявить делегат в C#?
Делегат похож на класс. вы можете создать его экземпляр, и вам нужно передать имя функции в качестве параметра в конструктор делегата.
Все делегаты неявно получены из System.Delegate
класса.
Пример:
public delegate int TestDelegate (string s);
Предыдущий делегат может использоваться для ссылки на любой метод с единственным строковым параметром и возвращает переменную типа int.
Синтаксис:
delegate <return type> <delegate-name> <parameter list>
Как настроить участников
Когда вы объявляете тип делегата, вам нужно создать объект-делегат с новым ключевым словом и связать его с определенным методом.
При создании делегата аргумент, передаваемый новому выражению, аналогичен вызову метода, но без аргументов метода.
Пример:
using System; delegate int NumberChanger(int n); namespace DelegateAppl { class TestDelegate { static int num = 10; public static int AddNum(int p) { num += p; return num; } public static int MultNum(int q) { num *= q; return num; } public static int getNum() { return num; } static void Main(string[] args) { //создавать экземпляры делегата NumberChanger nc1 = new NumberChanger(AddNum); NumberChanger nc2 = new NumberChanger(MultNum); //вызов методов с использованием объектов делегата nc1(25); Console.WriteLine("Value of Num: {0}", getNum()); nc2(5); Console.WriteLine("Value of Num: {0}", getNum()); Console.ReadLine(); } }}
Вызов делегата
После создания объекта-делегата объект-делегат передается другому коду, который будет вызывать делегат.
Объект-делегат вызывается с использованием имени объекта-делегата, за которым следуют аргументы в скобках, которые передаются делегату.
Пример вызова делегата:
TestDelegate(s);
MultiCasting делегат
Многоадресный делегат является делегатом, который имеет ссылки на несколько функций. Когда вы выполняете многоадресный делегат, все функции, на которые указывает делегат, также вызываются.
Существует два способа создания многоадресного делегата.
- + или + = для регистрации метода с делегатом
- - или - = отменить регистрацию метода с делегатом
Многоадресный делегат вызывает методы в списке вызовов в том же порядке, в котором они добавлены.
Если у делегата есть тип возврата, отличный от void, и если делегат является делегатом многоадресной рассылки, возвращается только значение последнего вызванного метода.
using System; delegate int NumberChanger(int n); namespace DelegateAppl { class TestDelegate { static int num = 10; public static int AddNum(int p) { num += p; return num; } public static int MultNum(int q) { num *= q; return num; } public static int getNum() { return num; } static void Main(string[] args) { //создавать экземпляры делегата NumberChanger nc1 = new NumberChanger(AddNum); NumberChanger nc2 = new NumberChanger(MultNum); //вызов методов с использованием объектов делегата nc1(25); Console.WriteLine("Value of Num: {0}", getNum()); nc2(5); Console.WriteLine("Value of Num: {0}", getNum()); Console.ReadLine(); } }}
Разница между делегатами и интерфейсами
Делегаты полезны, когда:
- Вызывается один метод.
- Класс может захотеть иметь несколько реализаций спецификации метода.
- Желательно разрешить использование статического метода для реализации спецификации.
- Желателен шаблон, подобный событию
- Вызывающему не нужно знать или получать объект, на котором определен метод.
- Поставщик реализации хочет «раздавать» реализацию спецификации только нескольким компонентам выбора.
- Желательна легкая композиция.
Интерфейсы полезны, когда:
- Спецификация определяет набор связанных методов, которые будут вызываться.
- Класс обычно реализует спецификацию только один раз.
- Вызывающий интерфейс хочет передать в тип интерфейса или из него, чтобы получить другие интерфейсы или классы.