Введение в универсальные шаблоны. (Руководство по программированию на 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#)