Книга: 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.

Оглавление книги


Генерация: 0.081. Запросов К БД/Cache: 0 / 0
поделиться
Вверх Вниз