Выбор класса коллекции
Внимательно относитесь к выбору класса коллекции. Неправильный тип может ограничить возможности использования коллекции.
Внимание
Не используйте такие типы в пространстве имен System.Collections. Рекомендуется использовать универсальные и параллельные версии коллекций из-за более высокой безопасности типов и других усовершенствований.
Оцените следующие вопросы.
Нужен ли вам последовательный список, элемент которого обычно удаляется сразу после извлечения его значения?
Если да, то рассмотрите возможность использования класса Queue или универсального класса Queue<T>, если требуется обработка по принципу "первым поступил — первым обслужен" (FIFO). Рассмотрите возможность использования класса Stack или универсального класса Stack<T>, если требуется обработка по принципу "последним поступил — первым обслужен" (LIFO). Для безопасного доступа из нескольких потоков используйте параллельные версии классов ConcurrentQueue<T> и ConcurrentStack<T>. Для неизменности рассмотрите неизменяемые версии, ImmutableQueue<T> и ImmutableStack<T>.
Если нет, то следует использовать другие коллекции.
Нужен ли доступ к элементам в определенном порядке (FIFO, LIFO) или в произвольным порядке?
Класс Queue, а также универсальные классы Queue<T>, ConcurrentQueue<T> и ImmutableQueue<T> предоставляют доступ по методу FIFO. Дополнительные сведения см. в разделе Преимущества использования потокобезопасных коллекций.
Класс Stack, а также универсальные классы Stack<T>, ConcurrentStack<T> и ImmutableStack<T> предоставляют доступ по методу LIFO. Дополнительные сведения см. в разделе Преимущества использования потокобезопасных коллекций.
Универсальный класс LinkedList<T> предоставляет последовательный доступ от начала к концу списка или наоборот.
Требуется ли доступ к каждому элементу по индексу?
Классы ArrayList и StringCollection и универсальный класс List<T> предоставляют доступ к элементам по отсчитываемому от нуля индексу элемента. Для неизменности рассмотрите неизменяемые универсальные версии, ImmutableArray<T> и ImmutableList<T>.
Классы Hashtable, SortedList, ListDictionary и StringDictionary и универсальные классы Dictionary<TKey,TValue> и SortedDictionary<TKey,TValue> предоставляют доступ к элементам по ключу элемента. Кроме того, существуют неизменяемые версии нескольких соответствующих типов: ImmutableHashSet<T>, ImmutableDictionary<TKey,TValue>, ImmutableSortedSet<T> и ImmutableSortedDictionary<TKey,TValue>.
Классы NameObjectCollectionBase и NameValueCollection и универсальные классы KeyedCollection<TKey,TItem> и SortedList<TKey,TValue> предоставляют доступ к элементам по отсчитываемому от нуля индексу или по ключу элемента.
Будет ли каждый элемент содержать только одно значение, сочетание из одного ключа и одного значения или сочетание из одного ключа и нескольких значений?
Одно значение: используйте любую коллекцию, основанную на интерфейсе IList или на универсальном интерфейсе IList<T>. Для неизменяемого параметра рассмотрим универсальный интерфейс IImmutableList<T>.
Один ключ и одно значение: используйте любую коллекцию, основанную на интерфейсе IDictionary или на универсальном интерфейсе IDictionary<TKey,TValue>. Для неизменяемого параметра рассмотрим универсальный интерфейс IImmutableSet<T> или IImmutableDictionary<TKey,TValue>.
Одно значение с внедренным ключом: используйте универсальный класс KeyedCollection<TKey,TItem>.
Один ключ и несколько значений: используйте класс NameValueCollection.
Требуется ли сортировать элементы в порядке, отличном от порядка их поступления?
Класс Hashtable сортирует элементы по хэш-коду.
В классе SortedList и универсальных классах SortedList<TKey,TValue> и SortedDictionary<TKey,TValue> элементы сортируются по ключу. Порядок сортировки зависит от реализации интерфейса IComparer для класса SortedList и от реализации универсального интерфейса IComparer<T> для универсальных классов SortedList<TKey,TValue> и SortedDictionary<TKey,TValue>. Из двух универсальных типов SortedDictionary<TKey,TValue> обеспечивает более высокую производительность, чем SortedList<TKey,TValue>, но SortedList<TKey,TValue> потребляет меньше памяти.
Класс ArrayList предоставляет метод Sort, который принимает реализацию IComparer в качестве параметра. Его универсальный аналог, универсальный класс List<T>, предоставляет метод Sort, который принимает реализацию универсального интерфейса IComparer<T> в качестве параметра.
Требуются ли быстрый поиск и получение данных?
- ListDictionary быстрее, чем Hashtable, для небольших коллекций (10 элементов или меньше). Универсальный класс Dictionary<TKey,TValue> обеспечивает более быстрый поиск, чем универсальный класс SortedDictionary<TKey,TValue>. Многопоточной реализацией является ConcurrentDictionary<TKey,TValue>. ConcurrentBag<T> обеспечивает быструю многопоточную вставку для неупорядоченных данных. Дополнительные сведения об обоих многопоточных типах см. в разделе Преимущества использования потокобезопасных коллекций.
Требуются ли вам коллекции, принимающие только строки?
Классы StringCollection (на основе IList) и StringDictionary (на основе IDictionary) находятся в пространстве имен System.Collections.Specialized.
Кроме того, можно использовать любой из универсальных классов коллекций в пространстве имен System.Collections.Generic как строго типизированную строковую коллекцию, указав класс String в качестве аргумента универсального типа. Например, можно объявить переменную типа "Строка> списка"<или "Строка словаря<", "Строка".>
LINQ to Objects и PLINQ
Язык LINQ to Objects позволяет использовать запросы LINQ для доступа к объектам в памяти при условии, что тип объекта реализует интерфейс IEnumerable или IEnumerable<T>. Запросы LINQ обеспечивают общий шаблон для доступа к данным, обычно являются более четкими и удобочитаемыми, чем стандартные циклы foreach
, а также предоставляют возможности фильтрации, сортировки и группировки. Дополнительные сведения см. в разделах LINQ to Objects (C#) и LINQ to Objects (Visual Basic).
Язык PLINQ предоставляет параллельную реализацию языка LINQ to Objects, которая может обеспечить более быстрое выполнение запросов во многих сценариях за счет более эффективного использования многоядерных компьютеров. Дополнительные сведения см. в разделе Parallel LINQ (PLINQ).