Книга: C# 4.0: полное руководство
Обобщенные делегаты
Обобщенные делегаты
Как и методы, делегаты также могут быть обобщенными. Ниже приведена общая форма объявления обобщенного делегата.
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
.
- Что такое обобщения
- Простой пример обобщений
- Обобщенный класс с двумя параметрами типа
- Общая форма обобщенного класса
- Получение значения, присваиваемого параметру типа по умолчанию
- Обобщенные структуры
- Создание обобщенного метода
- Обобщенные делегаты
- Обобщенные интерфейсы
- Сравнение экземпляров параметра типа
- Иерархии обобщенных классов
- Переопределение виртуальных методов в обобщенном классе
- Перегрузка методов с несколькими параметрами типа
- Ковариантность и контравариантность в параметрах обобщенного типа
- Создание экземпляров объектов обобщенных типов
- Некоторые ограничения, присущие обобщениям
- Заключительные соображения относительно обобщений
- Обобщенные структуры
- Обобщенные интерфейсы
- Обобщенные коллекции
- Делегаты в качестве параметров
- 3.9. Обобщенные регулярные выражения
- ГЛАВА 15 Делегаты, события и лямбда-выражения
- Делегаты
- Необобщенные коллекции
- Обобщенные подпрограммы: обзор
- Обобщенные типы
- Обобщенные подпрограммы в качестве параметров
- ГЛАВА 8. Интерфейсы обратного вызова, делегаты и события