Поделиться через


Введение в универсальные шаблоны. (Руководство по программированию на C#)

Способ, которым универсальные классы и методы сочетают возможность многократного использования, строгую типизацию и эффективность, отличается от способа, используемого их нестандартными аналогами. Чаще всего универсальные шаблоны используются с функционирующими с ними коллекциями и методами. Библиотека классов в платформе .NET Framework версии 2.0 предоставляет новое пространство имен, System.Collections.Generic, содержащее несколько новых универсальных классов коллекций. Во всех приложениях, предназначенных для выполнения в .NET Framework 2.0 и более поздней версии, вместо старых нестандартных аналогов, таких как ArrayList, рекомендуется использовать новые универсальные классы коллекции. Дополнительные сведения см. в разделе Универсальные шаблоны в библиотеке классов платформы .NET Framework (Руководство по программированию в C#).

Разумеется, чтобы получить собственные типобезопасные и эффективные обобщенные решения и шаблоны разработки, можно создать пользовательские универсальные типы и методы. В следующем примере кода в демонстрационных целях показан простой универсальный класс, реализующий связанный список. (В большинстве случаев следует использовать класс List, предоставленный библиотекой классов платформы .NET Framework, а не создавать собственный.) Параметр-тип T используется в нескольких местах, где конкретный тип обычно использовался бы для указания типа элемента, хранящегося в списке. Его можно использовать следующим образом:

  • в качестве типа параметра метода в методе AddHead;

  • в качестве возвращаемого типа свойства GetNext и Data открытого метода во вложенном классе Node;

  • в качестве типа данных закрытого члена во вложенном классе.

Обратите внимание, что T доступен для вложенного класса Node. Когда будет создан GenericList<T> с конкретным типом, например как GenericList<int>, каждое вхождение T будет заменено int.

// type parameter T in angle brackets 
public class GenericList<T> 
{
    // The nested class is also generic on T. 
    private class Node
    {
        // T used in non-generic constructor. 
        public Node(T t)
        {
            next = null;
            data = t;
        }

        private Node next;
        public Node Next
        {
            get { return next; }
            set { next = value; }
        }

        // T as private member data type. 
        private T data;

        // T as return type of property. 
        public T Data  
        {
            get { return data; }
            set { data = value; }
        }
    }

    private Node head;

    // constructor 
    public GenericList() 
    {
        head = null;
    }

    // T as method parameter type: 
    public void AddHead(T t) 
    {
        Node n = new Node(t);
        n.Next = head;
        head = n;
    }

    public IEnumerator<T> GetEnumerator()
    {
        Node current = head;

        while (current != null)
        {
            yield return current.Data;
            current = current.Next;
        }
    }
}

Следующий пример кода показывает, как клиентский код использует класс GenericList<T> для создания списка целых чисел. Благодаря простому изменению аргумента-типа, следующий код можно легко преобразовать для создания списка строк или любого другого пользовательского типа.

class TestGenericList
{
    static void Main()
    {
        // int is the type argument
        GenericList<int> list = new GenericList<int>();

        for (int x = 0; x < 10; x++)
        {
            list.AddHead(x);
        }

        foreach (int i in list)
        {
            System.Console.Write(i + " ");
        }
        System.Console.WriteLine("\nDone");
    }
}

См. также

Ссылки

Универсальные шаблоны (Руководство по программированию на C#)

System.Collections.Generic

Основные понятия

Руководство по программированию на C#