Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
CSharp_Prog_Guide.doc
Скачиваний:
16
Добавлен:
16.11.2019
Размер:
6.22 Mб
Скачать

Определение коллекций

Коллекция представляет собой набор объектов схожих типов, сгруппированных вместе.

Объекты любого типа могут быть сгруппированы в одну коллекцию типа Object, чтобы воспользоваться преимуществами конструкций, свойственных определенному языку. Например, оператор foreach языка C# (for each в Visual Basic) предполагает, что все объекты коллекции имеют один и тот же тип.

Однако в коллекции типа Object происходит дополнительная индивидуальная обработка элементов, к примеру, упаковка и распаковка или преобразования, что влияет на производительность коллекции. Упаковка и распаковка обычно происходят при сохранении или извлечении типа значений из коллекции типа Object.

Универсальные коллекции, такие как List<(Of <(T>)>) и строго типизированные неуниверсальные коллекции, такие как StringCollection, позволяют избежать проблем с производительностью, если тип элемента является типом, для которого предназначена коллекция (например, сохранение или извлечение строк из StringCollection). Кроме того, при добавлении элемента в строго типизированную коллекцию выполняется автоматическая проверка типа такого элемента.

Все коллекции, которые прямо или косвенно реализуют интерфейс ICollection или универсальный интерфейс ICollection<(Of <(T>)>) имеют несколько общих функциональных возможностей наряду с методами, которые выполняют добавление, удаление или поиск элементов:

  • Перечислитель.

Перечислитель — это объект, который выполняет итерацию в связанной с ним коллекции. Можно считать, что он является перемещаемым указателем на любой элемент коллекции. Перечислитель может быть связан только с одной коллекцией, но коллекция может иметь несколько перечислителей. Оператор foreach языка C# (for each в Visual Basic) использует перечислитель и упрощает обращение с перечислителем.

  • Элементы синхронизации.

Синхронизация обеспечивает потокобезопасность при доступе к элементам коллекции. По умолчанию коллекции не являются потокобезопасными. Только несколько классов в пространствах имен System.Collections предоставляют метод Synchronize, который создает потокобезопасную обертку для коллекции. Однако все классы во всех пространствах имен System.Collections предоставляют свойство SyncRoot, которое может быть использовано производными классами для создания собственной потокобезопасной обертки. Свойство IsSynchronized также используется для определения потокобезопасности коллекции. Синхронизация недоступна в универсальном интерфейсе ICollection<(Of <(T>)>).

  • CopyTo метод.

Все коллекции могут быть скопированы в массив с помощью метода CopyTo; однако порядок элементов в новом массиве зависит от того, в какой последовательности их возвращает перечислитель. Результирующий массив всегда является одномерным массивом с нижней границей, равной нулю.

Обратите внимание, что универсальный интерфейс ICollection<(Of <(T>)>) имеет дополнительные члены, которые отсутствуют в ICollection.

The following features are implemented in some classes in the System.Collections namespaces:

  • Capacity and count.

The capacity of a collection is the number of elements it can contain. The count of a collection is the number of elements it actually contains. A BitArray is a special case; its capacity is the same as its length, which is the same as its count. Some collections hide the capacity or the count or both.

All collections in the System.Collections namespaces automatically expand in capacity when the current capacity is reached. The memory is reallocated, and the elements are copied from the old collection to the new one. This reduces the code required to use the collection; however, the performance of the collection might still be negatively affected. The best way to avoid poor performance caused by multiple reallocations is to set the initial capacity to be the estimated size of the collection.

  • Lower Bound.

The lower bound of a collection is the index of its first element. All indexed collections in the System.Collections namespaces have a lower bound of zero. Array has a lower bound of zero by default, but a different lower bound can be defined when creating an instance of the Array class using CreateInstance.

System.Collections classes can generally be categorized into three types:

  • Commonly used collections.

These are the common variations of data collections, such as hash tables, queues, stacks, dictionaries, and lists. Commonly used collections have generic versions and nongeneric versions.

  • Bit collections.

These are collections whose elements are bit flags. They behave slightly differently from other collections.

  • Specialized collections.

These are collections with highly specific purposes, usually to handle a specific type of element, such as StringDictionary.

Be sure to choose a collection class carefully. Because each collection has its own functionality, each also has its own limitations. The more specialized a collection is, the more limited it is.

В некоторых классах пространств имен System.Collections реализованы следующие возможности:

  • Емкость и количество элементов.

Емкость коллекции — это число элементов, которое она может содержать. Количество элементов коллекции — это число элементов, которое она реально содержит. BitArray является особым случаем; её емкость совпадает с его длиной, которая совпадает с количеством элементов коллекции. Некоторые коллекции скрывают емкость и/или количество элементов.

Все коллекции пространств имен System.Collections автоматически увеличивают емкость, если количество элементов достигает предела. Происходит перераспределение памяти, и элементы копируются из старой коллекции в новую. Это уменьшает объем кода, необходимого для использования коллекции; однако производительность при работе с такой коллекцией может ухудшиться. Наилучший способ избежать потерь производительности, вызванных множественными перераспределениями, это установить начальную вместимость, равную предполагаемому размеру коллекции.

  • Нижняя граница.

Нижняя граница коллекции — это индекс ее первого элемента. Все индексированные коллекции в пространствах имен System.Collections имеют нижнюю границу, равную нулю. Array имеет нижнюю границу, равную нулю, по умолчанию, но при создании экземпляра Array с помощью CreateInstance может быть определена другая нижняя граница.

Обычно классы System.Collections можно разделить на три типа:

  • Часто используемые коллекции.

Это распространенные виды коллекций данных, такие как хэш-таблицы, очереди, стеки, словари и списки. Часто используемые коллекции имеют свои универсальные и неуниверсальные версии.

  • Битовые коллекции.

Это коллекции, элементами которых являются битовые флаги. Их поведение слегка отличается от поведения других коллекций.

  • Специализированные коллекции.

Эти коллекции предназначены для реализации очень узких задач, обычно для обработки элементов определенного типа. К таким классам относится StringDictionary.

Следует тщательно выбирать класс коллекции. Наряду с определенными функциональными возможностями каждая коллекция имеет также и собственные ограничения. Чем более специализированной является коллекция, тем она более ограничена.

Selecting a Collection Class

Be sure to choose your System.Collections class carefully. Using the wrong type can restrict your use of the collection.

Consider the following questions:

  • Do you need a sequential list where the element is typically discarded after its value is retrieved?

    • If yes, consider using the Queue class or the Queue<(Of <(T>)>) generic class if you need first-in-first-out (FIFO) behavior. Consider using the Stack class or the Stack<(Of <(T>)>) generic class if you need last-in-first-out (LIFO) behavior.

    • If not, consider using the other collections.

  • Do you need to access the elements in a certain order, such as FIFO, LIFO, or random?

    • The Queue class and the Queue<(Of <(T>)>) generic class offer FIFO access.

    • The Stack class and the Stack<(Of <(T>)>) generic class offer LIFO access.

    • The LinkedList<(Of <(T>)>) generic class allows sequential access either from the head to the tail or from the tail to the head.

    • The rest of the collections offer random access.

  • Do you need to access each element by index?

    • The ArrayList and StringCollection classes and the List<(Of <(T>)>) generic class offer access to their elements by the zero-based index of the element.

    • The Hashtable, SortedList, ListDictionary, and StringDictionary classes, and the Dictionary<(Of <(TKey, TValue>)>) and SortedDictionary<(Of <(TKey, TValue>)>) generic classes offer access to their elements by the key of the element.

    • The NameObjectCollectionBase and NameValueCollection classes, and the KeyedCollection<(Of <(TKey, TItem>)>) and SortedList<(Of <(TKey, TValue>)>) generic classes offer access to their elements by either the zero-based index or the key of the element.