- •Тема 2.8. Виртуальные функции в c#
- •Что такое «Виртуальные функции»?
- •Как объявляются виртуальные функции?
- •Абстрактные функции и абстрактные классы
- •Модификатор sealed
- •Реализация виртуального механизма
- •Класс с универсальными методами
- •Тема 2_09. Универсальные (параметризованные) классы. Шаблоны
- •Наследование и универсальность
- •Синтаксис универсального класса
- •Два основных механизма объектной технологии
- •Ограниченная универсальность
- •Синтаксис ограничений
- •Framework .Net и универсальность
Тема 2_09. Универсальные (параметризованные) классы. Шаблоны
Дополнительные сведения см. в файле «Лекции по C# В_А_Биллинг.pdf», 22. Лекция: Универсальность. Классы с родовыми параметрами
Наследование и универсальность
Суть универсальности в том, чтобы в момент вызова процедуры передавать ей не только фактические аргументы, но и их фактический тип.
Необходимость в универсализации возникает с первых шагов программирования. Одна из первых процедур, появляющихся при обучении программированию - это процедура свопинга: обмен значениями двух переменных одного типа. Выглядит она примерно так:
public void Swap(ref T x1, ref T x2)
{
T temp;
temp = x1; x1 = x2; x2 = temp;
}
Как быть, если возникает необходимость обмена данными разного типа? В типизированных языках, не обладающих механизмом универсализации, выхода практически нет - приходится писать многочисленные копии Swap.
Для достижения универсальности процедуры Swap следует рассматривать тип T как ее параметр, такой же, как и сами аргументы x1 и x2.
Под универсальностью (genericity) понимается способность класса объявлять используемые им типы как параметры. Класс с параметрами, задающими типы, называется универсальным классом (generic class). Терминология не устоялась и синонимами термина "универсальный класс" являются термины: родовой класс, параметризованный класс, класс с родовыми параметрами. В языке С++ универсальные классы называются шаблонами (template).
Синтаксис универсального класса
Объявить класс C# универсальным просто: для этого достаточно указать в объявлении класса, какие из используемых им типов являются параметрами. Список типовых параметров класса, заключенный в угловые скобки, добавляется к имени класса:
class MyClass<T1, ... Tn>
{...}
Как и всякие формальные параметры, Ti являются именами (идентификаторами). При вызове они заменяются на названия типов данных (int, string, Color, Figure и т.п.).
В теле класса типовые параметры могут задавать типы некоторых полей класса, типы аргументов и возвращаемых значений методов класса.
В C# универсальными могут быть как классы, так и все их частные случаи - интерфейсы, структуры, делегаты, события.
Класс с универсальными методами
Специальным частным случаем универсального класса является класс, не объявляющий сам параметров, но разрешающий делать это своим методам.
class Change
{
static public void Swap<T>(ref T x1, ref T x2)
{
T temp;
temp = x1; x1 = x2; x2 = temp;
}
}
Пример вызова:
Change.Swap<int>(ref x1, ref x2);
Change.Swap<string>(ref s1, ref s2);
Change.Swap<Person>(ref pers1, ref pers2);
В момент вызова метода передаются фактические аргументы и фактические типы. В данном примере в качестве фактических типов использовались встроенные типы int и string и тип Person, определенный пользователем. Общая ситуация такова: если в классе объявлен универсальный метод со списком параметров
M<T1, ...Tn> (...),
то метод вызывается следующим образом:
M<TYPE1, ... TYPEn>(...), где TYPEi - это конкретные типы.
