Обобщенные делегаты
Перед изучением данной темы рекомендуется ознакомиться со следующими темами:
- Понятие делегата. Объявление типа делегата. Использование делегата в программе. Групповое преобразование методов
- Обобщения. Основные понятия. Обобщенные классы и структуры
Содержание
- 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
⇑
Связанные темы
- Понятие делегата. Объявление типа делегата. Использование делегата в программе. Групповое преобразование методов
- Обобщения. Основные понятия. Обобщенные классы и структуры
- Обобщенные интерфейсы. Синтаксис объявления. Реализация обобщенных интерфейсов в классах. Примеры
- Обобщенные методы в классах. Синтаксис объявления. Способы вызова
⇑