public int Count { get { return arInts.Count; } }
IEnumerator IEnumerable.GetEnumerator() { return arInts.GetEnumerator(); }
}
Вне зависимости от того, какой тип вы выберете для хранения целых чисел (System.Array, System.Collections.ArrayList и т.п.), вы не сможете избавиться от проблемы .NET 1.1, связанной с созданием объектных образов. Нетрудно догадаться, что здесь снова на помощь приходят обобщения. В следующем фрагменте программного кода тип System.Collections.Generic.List‹› используется для создания контейнера целых чисел, не имеющего проблем создания объектных образов и восстановлений значений при вставке и получении типов характеризуемых значений.
static void Main (string [] args) {
// Баз создания объектного образа!
List‹int› myInts = new List‹int›();
myInts.Add.(5);
// Без восстановления значения!
int i = myInts[0];
}
Просто в качестве подтверждения рассмотрите следующий CIL-код для этого метода Main() (обратите внимание да отсутствие в нем каких бы то ни было блоков box и unbox).
.method private hidebysig static void Main(string[] args) cil managed {
.entrypoint
// Code size 24 (0x18)
.maxstack 2
.locals init ([0] class [mscorlib] System.Collections.Generic.List`1‹int32› myInts, [1] int32 i)
IL_0000: nop
IL_0001: newobj instance void class [mscorlib] System.Collections.Generic.List`1‹int32›::.ctor()
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: ldc.i4.5
IL_0009: callvirt instance void class [mscorlib]System.Collections.Generic.List`1‹int32›::Add(!0)
IL_000e: nop
IL_000f: ldloc.0
IL_0010: ldc.i4.0
IL_0011: callvirt instance !0 class [mscorlib]System.Collections.Generic.List`1‹int32›::get_Item(int32)
IL_0016: stloc.1
IL_0017: ret
} // end of method Program::Main
Теперь, когда вы имеете лучшее представление о роли обобщений в .NET2.0, мы с вами готовы углубиться в детали. Для начала мы формально рассмотрим пространство имен System.Collections.Generic.
Исходный код.Проект CustomNonGenericCollection размещен в подкаталоге, соответствующем главе 10.
Пространство имен System.Collections.Generic
Обобщенные типы присутствуют во многих библиотеках базовых классов .NET 2.0, но пространство имен System.Collections.Generic буквально наполнено ими (что вполне соответствует его названию). Подобно своему "родственнику" без обобщений (System.Collections), пространство имен System.Collections. Generic содержит множество типов класса и интерфейса, что позволяет вкладывать элементы в самые разные контейнеры. Совсем не удивительно, что обобщенные интерфейсы имитируют соответствующие необобщенные типы из пространства имен System.Collections.
• ICollection‹T›
• IComparer‹T›
• IDictionary‹K, V›
• IEnumerable‹T›
• IEnumerator‹T›
• IList‹T›
Замечание.По соглашению для обобщенных типов их замещаемые параметры обозначаются буквами верхнего регистра. И хотя здесь допустимо использовать любые буквы (или слова), обычно используют Т для обозначения типов, К – для ключей, а V – для значений.
В пространстве имен System.Collections.Generic определяется и ряд классов, реализующих многие из этих ключевых интерфейсов. В табл. 10.1 представлены описания базовых типов класса из этого пространства имен, реализуемые ими интерфейсы и соответствующие типы из пространства имен System.Collections.
В пространстве имен 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 |
Обобщенная реализация набора элементов только для чтения |
Читать дальше