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

18.4. Обобщённые структуры "обобщённые структуры"

Правила объявления и использования обобщенных структур не отличаются от

правил для обобщенных классов. Для обобщенных структур типизирующие

параметры указываются в угловых скобках вслед за именем структурного типа. Для

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

ограничений те же, что и для классов.

Так как у обобщенных структур много общего с обобщенными классами, то

рассмотрим здесь только те правила, о которых не говорилось в связи с классами

(хотя эти правила общие и для классов и для структур).

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

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

одноименных типов. При перегрузке обобщенных типов конкретный тип

определяется по числу аргументов, использованных при инстанцировании. Пример

перегрузки обобщенных структур:

struct Element<D> {

public D memb;

}

struct Element<E, R> {

public E memb1;

public R memb2;

}

В данном случае два открытых типа (два обобщенных структурных типа)

имеют одинаковые имена, но разное количество типизирующих параметров. Имена

этих параметров не имеют значения при перегрузке. Невозможно объявить в том же

пространстве имен, например, обобщенную структуру с заголовком struct

Element<T, F>.

Обобщенный

тип

называют

открытым

типом

"тип:открытый" ,

а

сконструированный на его основе полностью специфицированный тип – закрытым

"тип:закрытый" , подчеркивая, что на основе этого сконструированного типа уже

нельзя объявлять другие типы.

Пример переменной и экземпляра структуры закрытого типа:

Element<int> ded = new Element<int>();

Console.WriteLine("ded.memb = " + ded.memb);

Результат выполнения: ded.memb = 0

Как всегда по умолчанию члены структур инициализируются умалчиваемыми

значениями соответствующих типов. В нашем примере целочисленное поле

структуры равно нулю.

Следует отметить, что обобщенный тип и одноименный с ним регулярный тип

считаются разными типами. Например, наряду с обобщенным классом Example<U>

в той же программе можно декларировать такой регулярный класс "регулярный

класс" :

public class Example { }

Это не приведет к ошибочной ситуации.

Обобщенные типы могут включать статические члены. В этих случаях

каждый статический член обобщенного типа "статический член:обобщённого типа"

при создании сконструированных типов «размножается». То есть каждому

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

типа. Пример обобщённого типа структур со статическим членом (программа

18_02.cs):

using System;

struct memb<T> {

public static int count;

public T data;

public memb (T d){

data = d;

count++;

}

}

class Program {

static void Main( )

{

memb<char> mc1 = new memb<char>('Z');

memb<char> mc2 = new memb<char>('F');

memb<byte> mb = new memb<byte>(12);

Console.WriteLine("memb<char>.count = " + memb<char>.count);

Console.WriteLine("memb<byte>.count = " + memb<byte>.count);

}

}

}

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

memb<char>.count = 2

memb<byte>.count = 1

В обобщенный тип структур memb<T> входит счетчик экземпляров public

static int count; По умолчанию он инициализируется нулевым значением. При

каждом обращении к конструктору значение счетчика увеличивается на 1. Тип поля

данных data и тип параметра конструктора определяются типизирующим

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

В основной программе созданы два объекта закрытой структуры memb<char> и

один

экземпляр

типа

memb<byte>.

Результаты

выполнения

программы

иллюстрируют правило «размножения» статических членов обобщенных типов.

Статический член принадлежит не обобщенному типу, а в каждый из

сконструированных на его основе типов входит свой собственный статический член

(он в свою очередь может быть параметризован типизирующим параметром, но это

не показано в приведенном примере).

В качестве примера обобщенного структурного типа со статическими

методами рассмотрим такую программу (18_03.cs):

using System;

struct GenStr<T,V>{

static GenStr( ) { //статический конструктор

Console.Write("{0}+{1}", typeof(T).Name, typeof(V).Name);

}

public static void method( ) { } //статический метод

}

class Program {

static void Main( ) {

GenStr<string, int>.method( );

}

}

В обобщенном типе GenStr<T,V> объявлены статический конструктор и

статический метод method(), не имеющий параметров и «ничего не делающий». В

основной программе конструируется закрытый структурный тип GenStr<string, int>

и для него выполняется обращение к статическому методу method(). Тем самым

неявно вызывается статический конструктор, в теле которого выводятся названия

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

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

String+Int32

При

вложении

обобщенных

типов

"обобщённый

тип : вложение"

рекомендуется для типизирующих параметров внешнего и вложенного обобщенных

типов использовать разные идентификаторы. Предположим обратное, то есть

объявим такую обобщенную структуру, в теле которой объявлена другая

обобщённая структура:

struct memb<T> {

struct into<T> {

T field;

}

}

Объявление корректно, но при создании закрытого типа, например,

memb<int>, вложенная структура продолжает иметь открытый тип into<T>, и

конкретный тип поля field, остается, по крайней мере, непонятным. В следующем

примере показано корректное объявление вложенных обобщенных структур:

struct memb<T> {

struct into<U> {

T field1;

U field2;

}

}

Типизирующий параметр Т внешнего обобщенного типа доступен и в нем и в

о

вложенном типе. В то же время параметр U доступен только во вложенном

обобщенном типе. При таком объявлении закрытый тип memb<int> определяет тип

поля field1, но оставляет обобщенной структуру into<U> и не влияет на тип поля

field2.

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