Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Руководство_по_C#.doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
10.01 Mб
Скачать

11.11Обобщенные делегаты

Как и методы, делегаты также могут быть обобщенными. Ниже приведена общая форма объявления обобщенного делегата:

delegate возвращаемый_тип имя_делегата<список_параметров_типа>

(список_аргументов);

Обратите внимание на расположение списка параметров типа. Он следует непосредственно после имени делегата. Преимущество обобщенных делегатов заключается в том, что их допускается определять в типизированной обобщенной форме, которую можно затем согласовать с любым совместимым методом.

Обобщенные делегаты предоставляют более гибкий способ спецификации метода, подлежащего вызову в безопасной к типам манере. До появления обобщений (в .NET 2.0) того же конечного результата можно было достичь с использованием параметра System.Object:

public delegate void MyDelegate(object arg);

Хотя это позволяет посылать любой аргумент цели делегата, это не обеспечивает безопасность типов и не избавляет от необходимости упаковки/распаковки. Давайте рассмотрим пример применения обобщенных делегатов:

using System;

namespace ConsoleApplication1

{

// Создадим обобщенный делегат

delegate T MyDel<T>(T obj1, T obj2);

class MySum

{

public static int SumInt(int a, int b)

{ return a + b; }

public static string SumStr(string s1, string s2)

{ return s1 + " " + s2; }

public static char SumCh(char a, char b)

{ return (char)(a + b); }

}

class Program

{

static void Main()

{

// Реализуем несколько методов обобщенного делегата

MyDel<int> del1 = MySum.SumInt;

Console.WriteLine("6 + 7 = " + del1(6, 7));

MyDel<string> del2 = MySum.SumStr;

Console.WriteLine("\"Отличная\" + \"погода\" = " +

del2("Отличная", "погода"));

MyDel<char> del3 = MySum.SumCh;

Console.WriteLine("'a' + 'c' = " + del3('a', 'c'));

Console.ReadKey();

}

}

}

Выполнение программы:

6 + 7 = 13

"Отличная" + "погода" = Отличная погода

'a' + 'c' = A

11.12Обобщенные интерфейсы

Помимо обобщенных классов и методов, в C# допускаются обобщенные интерфейсы. Такие интерфейсы описываются аналогично обобщенным классам. Применяя обобщения, можно определять интерфейсы, объявляющие методы с обобщенными параметрами. Давайте рассмотрим пример применения обобщенных интерфейсов:

using System;

namespace ConsoleApplication1

{

// Объявляем обобщенный интерфейс

public interface ISort<T> where T : struct

{ void Print(); }

// Реализуем интерфейс в классе MyObj

class MyObj<T> : ISort<T> where T : struct

{

public int longOb { get; set; }

T[] myarr;

public MyObj(int i) { longOb = i; }

public MyObj(int i, T[] arr)

{

longOb = i;

myarr = new T[i];

for (int j = 0; j < arr.Length; j++) myarr[j] = arr[j];

}

public void Print()

{

Console.WriteLine("Тип: {0}", typeof(T));

Console.WriteLine("Массив объектов: ");

foreach (T t in myarr) Console.Write("{0}\t", t);

Console.WriteLine("\n");

}

}

class Program

{

static void Main()

{

byte[] MyArrByte = new byte[5] { 4, 5, 18, 56, 8 };

MyObj<byte> ByteConst = new MyObj<byte>(MyArrByte.Length,

MyArrByte);

ByteConst.Print();

float[] MyArrFloat = new float[8] { 12.0f, 1f, 3.4f,

2.8f, -334.7f, -2f, 7.89f, 0 };

MyObj<float> FloatConst = new MyObj<float>

(MyArrFloat.Length, MyArrFloat);

FloatConst.Print();

Console.ReadKey();

}

}

}

Выполнение программы:

Тип: System.Byte

Массив объектов:

4 5 18 56 8

Тип: System.Single

Массив объектов:

12 1 3,4 2,8 -334,7 -2 7,89 0

Как видите в данном примере объявляется обобщенный интерфейс ISort в котором используется метод Print(). Класс MyObj реализует данный интерфейс, при этом данный класс должен иметь такое же обобщение как и интерфейс который он реализует. Обратите внимание, что обобщенный интерфейс ISort использует ограничение на тип значения, поэтому данное ограничение необходимо указать и при объявлении класса MyObj. В методе Main() создается несколько разнотипных экземпляров данного класса, и используется реализованный метод Print().