На этом шаге мы рассмотрим создание и использование обобщенных делегатов.
Обобщенным может быть делегат. При объявлении обобщенного делегата обобщенные параметры указываются в угловых скобках после имени делегата. При создании экземпляра делегата значения обобщенных параметров указываются в угловых скобках после названия делегата. Как все это выглядит на практике, показано в примере ниже.
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace pr262_1 { // Обобщенный делегат: delegate X GenMeth<X,Y>(Y arg); // Класс: class MyClass { // Целочисленное поле: public int code; // Метод с символьным аргументом возвращает символьный // результат: public char getChar(char start) { return (char)(start + code); } } // Главный класс: class Program { // Статический метод с целочисленным аргументом // возвращает текстовый результат: static string getStr(int num) { return "Число " + num; } // Статический метод с текстовым аргументом возвращает // целочисленный результат: static int getInt(string txt) { return Int32.Parse(txt); } // Главный метод: static void Main() { // Объект класса: MyClass obj = new MyClass(); obj.code = 5; // Экземпляры обобщенного делегата: GenMeth<string, int> A = getStr; GenMeth<int, string> B = new GenMeth <int, string>(getInt); GenMeth<char, char> C = obj.getChar; // Вызов экземпляров делегата: Console.WriteLine(A(123)); Console.WriteLine(B("100") + 200); Console.WriteLine(C('A')); // Задержка: Console.ReadLine(); } } }
При выполнении программы получаем такой результат:
Рис.1. Результат работы приложения
В программе мы объявляем обобщенный делегат GenMeth с двумя обобщенными параметрами X и Y. В соответствии с описанием делегата, экземпляр делегата может ссылаться на метод, который имеет один аргумент типа Y и возвращает результат типа X. Фактически это означает, что при создании экземпляра делегата в качестве метода, на который экземпляр будет ссылаться, можно выбрать любой метод с одним аргументом, возвращающий результат.
В программе описан класс MyClass с целочисленным полем code. В классе есть метод getChar(). У метода символьный аргумент, и метод возвращает символьный результат. Результат метода вычисляется так: к коду символа, переданного аргументом методу, прибавляется значение поля code, и полученное значение является кодом символа-результата.
В главном классе описано несколько статических методов. Методу getStr() в качестве аргумента передается целочисленное значение, а результатом метод возвращает текстовую строку, получающуюся объединением текста "Число " и значения аргумента метода.
Статический метод getInt(), как предполагается, аргументом получает текстовое представление для целого числа, а результатом возвращает собственно число из текста (фактически метод дублирует работу статического метода Parse() из структуры Int32).
В главном методе программы создается объект obj класса MyClass, полю code этого объекта присваивается значение 5, после чего ссылка на метод getChar() объекта используется в команде
GenMeth<char, char> C = obj.getChar; ,
GenMeth<string, int> A = getStr;
GenMeth<int, string> B = new GenMeth <int, string>(getInt);
На следующем шаге мы рассмотрим ограничения на параметры типа.