Тема 15. Шаблоны классов

Универсальные шаблоны

Общие (или параметризованные) типы (generics) позволяют при описании классов, структур, методов и интерфейсов использовать параметризованные параметры (не указывать тип параметра в момент написания кода). Тип параметра определяется в момент объявления переменной соответствующего типа. Таким образом можно создать некоторый общий элемент, тип который можно использовать в дальнейшем для данных различных типов.

Параметризованные типы также называют универсальными шаблонами.

Пример: Графическая библиотека. Нужны классы точек экрана с целочисленными координатами и точек поверхности земли с дробными координатами.

Классическая реализация:

class PointInt
{
    public int X;
    public int Y;
}

class PointDouble
{
    public double X;
    public double Y;
}

Использование:

PointInt screenP = new PointInt();
screenP.X = 38;
screenP.Y = 162;

PointDouble geoP = new PointDouble();
geoP.X = 51.63;
geoP.Y = 38.12;

Реализация шаблоном:

class Point<T>
{
    public T X;
    public T Y;
}

class Program
{
    static void Main(string[] args)
    {
        Point<int> screenP = new Point<int>();
        screenP.X = 38;
        screenP.Y = 162;

        Point<double> geoP = new Point<double>();
        geoP.X = 51.63;
        geoP.Y = 38.12;
    }
}

Коллекции в C

Во многих приложениях требуется создавать группы связанных объектов и управлять этими группами. Существует два способа группировки объектов: создать массив объектов и создать коллекцию. Массивы удобнее всего использовать для создания и работы с фиксированным числом строго типизированных объектов.

Коллекции предоставляют более гибкий способ работы с группами объектов. В отличие от массивов, группа объектов в классе может динамически возрастать и сокращаться в соответствии с потребностями приложения. Некоторые коллекции допускают назначение ключа любому объекту, который добавляется в коллекцию, чтобы в дальнейшем можно было быстро извлечь связанный с ключом объект из коллекции.

Коллекция является классом, поэтому необходимо объявить новую коллекцию перед добавлением в неё элементов.

Если коллекция содержит элементы только одного типа данных, можно использовать один из классов в пространстве имен System.Collections.Generic. Универсальная коллекция обеспечивает безопасность типов, так что другие типы данных не могут быть в нее добавлены. При извлечении элемента из универсальной коллекции нет необходимости определять или преобразовывать его тип данных.

Коллекции в C# построены на основе универсальных шаблонов.

Специализированные контейнеры

List<T> - класс, представляющий последовательный список. Реализует интерфейсы IList<T>, ICollection<T>, IEnumerable<T>.

Dictionary<TKey, TValue> - класс коллекции, хранящей наборы пар "ключ-значение". Реализует интерфейсы ICollection<T>, IEnumerable<T>, IDictionary<TKey, TValue>.

LinkedList<T> - класс двухсвязанного списка. Реализует интерфейсы ICollection<T> и IEnumerable<T>.

Queue<T> - класс очереди объектов, работающей по алгоритму FIFO("первый вошел -первый вышел"). Реализует интерфейсы ICollection, IEnumerable<T>.

SortedSet<T> - класс отсортированной коллекции однотипных объектов. Реализует интерфейсы ICollection<T>, ISet<T>, IEnumerable<T>.

SortedList<TKey, TValue> - класс коллекции, хранящей наборы пар "ключ-значение", отсортированных по ключу. Реализует интерфейсы ICollection<T>, IEnumerable<T>, IDictionary<TKey, TValue>.

SortedDictionary<TKey, TValue> - класс коллекции, хранящей наборы пар "ключ-значение", отсортированных по ключу. В общем похож на класс SortedList<TKey, TValue>, основные отличия состоят лишь в использовании памяти и в скорости вставки и удаления.

Stack<T> - класс стека однотипных объектов. Реализует интерфейсы ICollection<T> и IEnumerable<T>.

Массивы и списки

Массивы являются наиболее распространёнными коллекциями объектов. Многие структуры данных и коллекции основаны на массивах. Так например строки и буферы реализованы массивами. Массивы обладают быстрой скоростью доступа по номеру элемента, но вставка новых элементов требует изменения размера массива и соответственно операций резервирования и освобождения памяти.

Списки, реализованные классом List более удобны в случаях когда необходимо вставлять элементы. Почти во всех случаях они могут использоваться вместо массивов. Класс List преднахначен для хранения элементов типа object. Использование класса List для других типов данных требует преодразования типов, что сказывается на произвдительности. В этом случае можно использовать классы List<T>, представляющие собой т.н. шаблоны классов в терминологии C++ или generic (дженерик) в терминологии C#.

Пример:

static void WriteList(IList l) {
    foreach (object o in l)
        Console.WriteLine(o.ToString());
}

static void Main(string[] args){

    List<object> cAll = new List<object>();

    cAll.Add(14);
    cAll.Add(72.93);
    cAll.Add("Hello.");
    WriteList(cAll);

    List<String> cStr = new List<String>;
    cStr.Add(14);     // Ошибка – коллекция хранит только строки
    cStr.Add(72.93); // Ошибка – коллекция хранит только строки
    cStr.Add("Hello.");

    Console.ReadLine();
}

Дополнительная литература

http://professorweb.ru/my/csharp/charp_theory/level12/12_1.php
http://professorweb.ru/my/csharp/charp_theory/level12/12_3.php
http://professorweb.ru/my/csharp/charp_theory/level12/12_4.php
http://metanit.com/sharp/tutorial/4.1.php
http://metanit.com/sharp/tutorial/4.4.php

results matching ""

    No results matching ""