В пространстве имен System.Collections.Generic также определяется целый ряд "вспомогательных" классов и структур для работы с конкретными контейнерами. Например, тип LinkedListNode‹T› представляет узел в обобщенном LinkedList‹T›, исключение KeyNotFoundException возникает при попытке доступа к элементу контейнера с несуществующим ключом и т.д.
Как видно из табл. 10.1, многие обобщенные классы коллекции имеют необобщенные аналоги в пространстве имен System.Collections (иногда даже с одинаковыми именами). В главе 7 было показано, как работать с такими необобщенными типами, поэтому дальше не предполагается рассматривать все их обобщенные "дубликаты". Мы рассмотрим только List‹T›, чтобы проиллюстрировать приемы использования обобщений. Если вам нужны подробности о других элементах пространства имен System.Collections.Generic, обратитесь к документации .NET Framework 2.0.
Таблица 10.1. Классы System.Collections.Generic
| Обобщенный класс | Необобщенный аналог в System.Collections | Описание |
|---|---|---|
| Collection‹T› | CollectionBase | База для обобщенной коллекции |
| Comparer‹T› | Comparer | Выполняет сравнение двух обобщенных объектов |
| Dictionary‹K, V› | Hashtable | Обобщенная коллекция пар имен и значений |
| List‹T› | ArrayList | Список элементов с динамически изменяемыми размерами |
| Queue‹T› | Queue | Обобщенная реализация списка FIFO (дисциплина обслуживания типа "очередь") |
| SortedDictionary‹K, V› | SortedList | Обобщенная реализаций сортированного набора пар имен и значений |
| Stack | Stack | Обобщенная реализация списка LIFO (дисциплина обслуживания типа "стек") |
| LinkedList‹T› | - | Обобщенная реализация двусвязного списка |
| ReadOnlyCoIlection‹T› | ReadOnlyCollectionBase | Обобщенная реализация набора элементов только для чтения |
Тип List‹T›
Подобно необобщенным классам, обобщенные классы являются объектами, размещаемыми в динамической памяти, поэтому для них следует использовать new со всеми необходимыми аргументами конструктора. Кроме того, вы должны указать типы, замещающие параметры, определенные обобщенным типом. Так, для System.Collections.Generic.List‹T› требуется указать одно значение, задающее вид элемента, с которым будет функционировать List‹T›
static void Main(string[] args) {
// Создается List для хранения целых чисел.
List‹int› myInts = new List‹int›;
// Создается List для хранения объектов SportsCar.
List‹SportsCar› myCars = new List
// Создается List для хранения объектов Person.
List‹Person› myPeople = new List‹Person›;
}
В этот момент вы можете поинтересоваться, что же на самом деле становится значением заполнителя. Открыв окно определения программного кода в Visual Studio 2005 (см. главу 2), вы увидите, что везде в определении типа List‹T› используется заполнитель Т. Ниже показана часть соответствующего листинга (обратите внимание на элементы, выделенные полужирным шрифтом).
// Часть листинга для типа List‹T›.
namespace System.Collections.Generic {
public class List‹T›: IList‹T›, ICollection‹T›, IEnumerable‹T›, IList, ICollection, IEnumerable {
…
public void Add(T item);
public IList‹T› AsReadOnly;
public int BinarySearch(T item);
public bool Contains(T item)
public void CopyTo(T[] array);
public int FindIndex(System.Predicate‹T› match);
public T FindLast(System.Predicate‹T› match);
public bool Remove(T item);
public int RemoveAll(System.Predicate‹T› match);
public T[] ToArray;