Узагальнені делегати
Перед вивченням даної теми рекомендується ознайомитись з наступними темами:
- Поняття делегату. Оголошення типу делегату. Використання делегатів у програмі. Групове перетворення методів
- Узагальнення. Основні поняття. Узагальнені класи та структури
Зміст
- 1. Узагальнені делегати. Особливості застосування. Синтаксис оголошення узагальненого делегату для декількох типів
- 2. Синтаксис оголошення узагальненого делегату для одного типу T
- 3. Приклад узагальненого делегату, що отримує параметром один тип T
- 4. Приклад узагальненого делегату, що отримує параметрами два типи T1, T2
- 5. Приклад оголошення та використання узагальненого делегату, що узгоджується зі статичними методами
- Зв’язані теми
Пошук на інших ресурсах:
1. Узагальнені делегати. Особливості застосування. Синтаксис оголошення узагальненого делегату для декількох типів
У мові C# допускається використання узагальнених делегатів, які отримують параметрами узагальнені типи. Перевага узагальнених делегатів полягає в тому, що створюється типізована узагальнена форма методу, яка потім узгоджується з конкретним методом будь-якого класу. Метод, що узгоджується з узагальненим делегатом повинен мати схожу сигнатуру. Конкретними методами можуть бути як статичні методи, так і методи екземпляру.
Узагальнені делегати дозволяють безпечно викликати будь-які методи, що відповідають його узагальненій формі.
Загальна форма оголошення узагальненого делегату наступна:
delegate return_type DelegateName<T1, T2, ..., TN>(arguments_list);
тут
- DelegateName – ім’я узагальненого делегату;
- T1, T2, TN – імена типів, якими оперує делегат;
- arguments_list – список аргументів, які отримує делегат.
Після такого оголошення можна створювати посилання на узагальнений делегат за наступною формою:
DelegateName<T1, T2, ..., TN> refDelegate<type1, type2, ..., typeN>;
тут
- DelegateName<T1, T2, …, TN> – ім’я типу узагальненого делегату;
- refDelegate – ім’я посилання на узагальнений делегат;
- type1, type2, typeN – імена типів оголошених у програмі або імена базових типів (int, char, string тощо).
Якщо оголошено посилання, то цьому посиланню можна присвоїти ім’я сумісного методу приблизно наступним чином:
refDelegate = obj.MethodName;
тут
- obj – ім’я екземпляру класу, який містить метод MethodName();
- MethodName – ім’я методу, який є сумісний з делегатом DelegateName. Поняття “сумісність” означає, що кількість та типи параметрів методу та делегату співпадають.
Після того, як посилання вказує на метод, є можливість викликати цей метод звичним способом
refDelegate(arguments_list);
тут
- arguments_list – перелік аргументів, що передаються в метод MethodName(), який викликається за посиланням refDelegate.
⇑
2. Синтаксис оголошення узагальненого делегату для одного типу T
Якщо делегат оголошується тільки для одного узагальненого типу T, то загальна форма такого оголошення наступна
delegate return_type DelegateName<T>(arguments_list);
тут
- DelegateName – ім’я узагальненого делегату;
- T – ім’я узагальненого типу делегату;
- arguments_list – список аргументів, які отримує делегат.
Відповідно оголошення посилання на делегат DelegateName<T> та його використання може бути таким
refDelegate = obj.MethodName; ... refDelegate(arguments_list);
тут
- refDelegate – посилання на делегат DelegateName<T>;
- arguments_list – перелік аргументів, що передаються в метод MethodName.
⇑
3. Приклад узагальненого делегату, що отримує параметром один тип T
У прикладі оголошується узагальнений делегат Equal<T>, який оперує типом T та отримує два параметри типу T. Делегат повертає значення типу bool, що визначає рівність (нерівність) двох отримуваних параметрів.
Також оголошується клас EqualOperations, який містить реалізацію методів EqualInt(), EqualShort(), EqualString(). Ці методи визначають рівність відповідно для типів int, short та string. Методи є сумісними з типом делегату Equal<T>.
using System; namespace ConsoleApp19 { // Узагальнений делегат delegate bool Equal<T>(T value1, T value2); // Клас, що містить методи, які є сумісними // з делегатом Equal<T> class EqualOperations { // Для типу int public bool EqualInt(int value1, int value2) { return value1 == value2; } // Для типу short public bool EqualShort(short value1, short value2) { return value1 == value2; } // Для типу string public bool EqualString(string value1, string value2) { return value1 == value2; } } class Program { static void Main(string[] args) { // 1. Оголосити екземпляр класу EqualOperations EqualOperations obj = new EqualOperations(); // 2. Використання делегату для типу int // 2.1. Сконструювати делегат з іменем delInt для типу int Equal<int> delInt = obj.EqualInt; // 2.2. Викликати метод за делегатом для типу int bool equalInt = delInt(5, 5); Console.WriteLine("equalInt(5,5) = {0}", equalInt); // 3. Використання делегату для типу string // 3.1. Сконструювати делегат з іменем delString Equal<string> delString = obj.EqualString; // 3.2. Викликати метод за делегатом для типу string bool equalString = delString("bestprog.net", "bestprog"); Console.WriteLine("equalString = {0}", equalString); Console.ReadKey(); } } }
Результат виконання програми
equalInt(5,5) = True equalString = False
⇑
4. Приклад узагальненого делегату, що отримує параметрами два типи T1, T2
У прикладі оголошується делегат, що використовує два типи T1, T2.
using System; namespace ConsoleApp19 { // Делегат, що використовує два типи T1, T2 delegate void Operation<T1, T2>(T1 value1, T2 value2); // Клас, що містить метод, який узгоджений з делегатом Operation<T1, T2> class Methods { public void Print(int value1, double value2) { Console.WriteLine("value1 = {0}", value1); Console.WriteLine("value2 = {0}", value2); } } class Program { static void Main(string[] args) { // Оголосити екземпляр класу Methods Methods obj = new Methods(); // Оголосити посилання на делегат Operation<T1, T2> Operation<int, double> refOp; // Присвоїти посиланню refOp адресу методу Print() refOp = obj.Print; // Викликати метод Print() за посиланням refOp refOp(23, 8.89); Console.ReadKey(); } } }
Результат виконання програми
value1 = 23 value2 = 8.89
⇑
5. Приклад оголошення та використання узагальненого делегату, що узгоджується зі статичними методами
Узагальнений делегат може бути застосований до статичних методів. У прикладі оголошується делегат для забезпечення сумісності зі статичними методами, які реалізують пошук мінімального значення для типів int та double. У функції main() демонструється використання делегату Min<T>.
using System; namespace ConsoleApp19 { // Узагальнений делегат, що отримує масив узагальненого типу T // та повертає значення типу T delegate T Min<T>(T[] array); // Клас, що містить методи пошуку мінімального значення // в масиві для різних числових типів class MinValues { // Пошук мінімального значення в масиві типу double public static double GetMinDouble(double[] array) { double min = array[0]; for (int i = 1; i < array.Length; i++) if (min > array[i]) min = array[i]; return min; } // Для типу int public static int GetMinInt(int[] array) { int min = array[0]; for (int i = 1; i < array.Length; i++) if (min > array[i]) min = array[i]; return min; } } class Program { static void Main(string[] args) { // 1. Використання делегату Min<T> для типу double. // 1.1. Оголосити тестувальний масив типу double double[] AD = { 2.3, 2.5, 1.8, 1.1, 2.8, 1.9 }; // 1.2. Оголосити посилання на делегат Min<T> для типу double Min<double> refDouble; // 1.3. Присвоїти посиланню статичний метод refDouble = MinValues.GetMinDouble; // 1.4. Викликати за посиланням refDouble метод GetMinDouble double minDouble = refDouble(AD); Console.WriteLine("minDouble = {0}", minDouble); // 2. Використання делегату для типу int // 2.1. Оголосити тестувальний масив int[] AI = { 22, 33, 13, 18, 19, 140, 18, 10, 134 }; // 2.2. Оголосити посилання на делегат Min<T> для типу int // та присвоїти йому статичний метод GetMinInt Min<int> refInt = MinValues.GetMinInt; // 2.3. Викликати за посиланням refInt метод GetMinInt int minInt = refInt(AI); Console.WriteLine("minInt = {0}", minInt); Console.ReadKey(); } } }
Після запуску програма видасть наступний результат
minDouble = 1.1 minInt = 10
⇑
Зв’язані теми
- Узагальнення. Основні поняття. Узагальнені класи та структури
- Узагальнені інтерфейси. Синтаксис оголошення. Реалізація узагальнених інтерфейсів у класах
- Узагальнені методи в класах. Синтаксис оголошення. Способи виклику
- Упакування та розпакування. Необхідність застосування узагальнень
⇑