Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
CSBasicCourse2ndedPodbelsky / CSBasicCourse2ndedPodbelsky.rtf
Скачиваний:
27
Добавлен:
22.03.2016
Размер:
11.9 Mб
Скачать

18.5. Обобщённые интерфейсы "обобщённый интерфейс"

Напомним, что членами интерфейса могут быть прототипы методов, свойств,

индексаторов, событий. В обобщенном интерфейсе типизирующие параметры

определяют типы возвращаемых значений и параметров членов интерфейса. Как и

для классов и структур признаком обобщенного интерфейса является список

типизирующих параметров в его объявлении. Типизирующие параметры – это

идентификаторы, разделенные запятыми и помещенные в угловые скобки. Пример:

public interface IExample<T> { // обобщенный интерфейс

char this[T index]{get; set;} // прототип индексатора

Int add(t X, t y); // прототип метода

}

В обобщенном интерфейсе IExample<T> один типизирующий параметр. Он

специфицирует тип параметра прототипа индексатора, а для прототипа метода –

определяет типы параметров.

Обобщенный интерфейс может быть реализован как обобщенным, так и

регулярным типом. Пример реализации обобщенного интерфейса обобщенным

классом:

// реализация обобщенным классом

class real<U> : IExample<U>

{

public char this[U r] {

get { return r.ToString()[0]}

set{ } }

public int add(U a, U b)

{ return a.GetHashCode() + b.GetHashCode(); }

}

В

реализации

индексатор

возвращает

первый

символ

строкового

представления индекса, использованного при обращении к индексатору. В качестве

реализации акссесора set использована "заглушка". Реализация метода add(U a, U b)

выполняет суммирование хеш-кодов аргументов. Так как методы ToString() и

GetHashCode() присущи всем классам языка C#, то в объявление обобщенного

класса не потребовалось включать ограничения на типизирующий параметр.

Применение обобщенного класса real<U> иллюстрирует следующий код

(програама 18_04.cs):

class Program {

static void Main( ) {

var temp1 = new real<int>();

var temp2 = new real<byte>();

Console.WriteLine(temp1[655]);

Console.WriteLine(temp1.add(950,6));

Console.WriteLine(temp2[155]);

Console.WriteLine(temp2.add(34, 6));

}

}

Результаты выполнения программы:

6

956

1

40

Регулярный тип (класс или структура) может реализовать несколько

специализаций интерфейсов, сконструированных на основе одного обобщенного

интерфейса. Общие принципы этого механизма иллюстрирует следующий код с

тривиальными реализациями членов интерфейсов (программа 18_05.cs):

struct Realization : IExample<string>, IExample<double> {

public char this[string st] { get { return '#'; } set { }}

public int add(string s1, string s2) { return -135; }

public char this[double d] { get { return (char)d; } set { }}

public int add(double d1, double d2) {return (int)(d1-d2);}

}

В данном случае регулярная структура struct Realization реализует два

интерфейса, сконструированных на основе обобщенного интерфейса interfac

e

IExample<T>. При такой реализации в структуре создаются перегруженные методы

add() и перегруженные индексаторы. В следующем фрагменте кода создается один

экземпляр структуры Realization и для него с аргументами разных типов

вызываются метод add() и индексатор.

Realization emplar = new Realization();

Console.WriteLine(emplar.add(5.6, 3.3));

Console.WriteLine(emplar.add("123", "abc"));

Console.WriteLine(emplar[5.6]);

Console.WriteLine(emplar["screb"]);

При выполнении этого кода в консольное окно выводятся следующие

значения:

2

-135

#

При реализации обобщенного интерфейса обобщенным типом необходимо

следить, чтобы не появлялись такие комбинации типизирующих аргументов,

которые приведут к дублированию интерфейса в этом типе.

Пример заголовка, который вызовет ошибку компиляции:

public class Example<H> : IExample<char>, IExample<H>

В этом классе предлагается реализовать сконструированный тип (интерфейс)

IExample<char> и обобщенный интерфейс IExample<H> с типизирующим

параметром H. В том случае, если при инстанцировании класса Example<H> вместо

параметра Н будет подставлен аргумент char, то возникнет конфликт, так как класс

должен будет реализовывать два одинаковых интерфейса, что невозможно.

Соседние файлы в папке CSBasicCourse2ndedPodbelsky