Обобщенные делегаты
Как и методы, делегаты также могут быть обобщенными. Ниже приведена общая форма объявления обобщенного делегата.
delegate возвратцаемый_тип имя_делегата<список_параметров_типа> (список_аргументов) ;
Обратите внимание на расположение списка параметров типа. Он следует непосредственно после имени делегата. Преимущество обобщенных делегатов заключается в том, что их допускается определять в типизированной обобщенной форме, которую можно затем согласовать с любым совместимым методом.
В приведенном ниже примере программы демонстрируется применение делегата SomeOp с одним параметром типа Т. Этот делегат возвращает значение типа Т и принимает аргумент типа Т.
// Простой пример обобщенного делегата,
using System;
// Объявить обобщенный делегат,
delegate T SomeOp<T>(T v);
class GenDelegateDemo {
// Возвратить результат суммирования аргумента,
static int Sum(int v) {
int result = 0;
for (int i = v; i > 0; i--) result += i;
return result;
}
// Возвратить строку, содержащую обратное значение аргумента,
static string Reflect(string str) {
string result = "";
foreach (char ch in str) result = ch + result;
return result;
}
static void Main() {
// Сконструировать делегат типа int.
SomeOp<int> intDel = Sum;
Console.WriteLine(intDel(3));
// Сконструировать делегат типа string.
SomeOp<string> strDel = Reflect;
Console.WriteLine(strDel("Привет"));
}
}
Эта программа дает следующий результат.
6
тевирП
Рассмотрим эту программу более подробно. Прежде всего обратите внимание на следующее объявление делегата SomeOp.
delegate Т SomeOp<T>(T v);
Как видите, тип Т может служить в качестве возвращаемого типа, несмотря на то, что параметр типа Т указывается после имени делегата SomeOp.
Далее в классе GenDelegateDemo объявляются методы Sum() и Reflect(), как показано ниже.
static int Sum(int v) {
static string Reflect(string str) {
Метод Sum() возвращает результат суммирования целого значения, передаваемого в качестве аргумента, а метод Reflect() — символьную строку, которая получается обращенной по отношению к строке, передаваемой в качестве аргумента.
В методе Main() создается экземпляр intDel делегата, которому присваивается ссылка на метод Sum().
SomeOp<int> intDel = Sum;
Метод Sum() принимает аргумент типа int и возвращает значение типа int, поэтому он совместим с целочисленным экземпляром делегата SomeOp.
Аналогичным образом создается экземпляр strDel делегата, которому присваивается ссылка на метод Reflect().
SomeOp<string> strDel = Reflect;
Метод Reflect() принимает аргумент типа string и возвращает результат типа string, поэтому он совместим со строковым экземпляром делегата SomeOp.
В силу присущей обобщениям типовой безопасности обобщенным делегатам нельзя присваивать несовместимые методы. Так, следующая строка кода оказалась бы ошибочной в рассматриваемой здесь программе.
SomeOp<int> strDel = Reflect; //Ошибка!
Ведь метод Reflect() принимает аргумент типа string и возвращает результат типа string, а следовательно, он несовместим с целочисленным экземпляром делегата SomeOp.
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОК