Я видел, как они использовались одинаково, и я беспокоюсь, что собираюсь пойти по пути в дизайне, который необратим, если я не пойму это лучше. Кроме того, я использую .NET.
.net
list
collections
Энтони Поттс
источник
источник
IList
,IList<T>
, иList<T>
т.д. Короче говоря, вы не имеете ни малейшего представления , будет ли это назвать. Полиморфизм исправляет это.ObservableCollection<T>
пример, в котором методы переопределяются для уведомления об изменениях.В C # существует три концепции представления набора объектов. В порядке увеличения характеристик это:
Enumerable не имеет порядка. Вы не можете добавлять или удалять предметы из набора. Вы даже не можете подсчитать количество предметов в наборе. Это строго позволяет вам получить доступ к каждому элементу в наборе, один за другим.
Коллекция - это изменяемый набор. Вы можете добавлять и удалять объекты из набора, вы также можете получить количество предметов в наборе. Но по-прежнему нет порядка, и потому что нет порядка: нет возможности получить доступ к элементу по индексу, и нет никакого способа сортировки.
Список - это упорядоченный набор объектов. Вы можете отсортировать список, получить доступ к элементам по индексу, удалить элементы по индексу.
Фактически, если посмотреть на их интерфейсы, они основаны друг на друге:
interface IEnumerable<T>
GetEnumeration<T>
interface ICollection<T> : IEnumerable<T>
Add
Remove
Clear
Count
interface IList<T> = ICollection<T>
Insert
IndexOf
RemoveAt
При объявлении переменных или параметров метода вы должны использовать
Исходя из концептуально, что нужно делать с набором объектов.
Если вам просто нужно иметь возможность что-то делать с каждым объектом в списке, вам нужно только
IEnumerable
:void SaveEveryUser(IEnumerable<User> users) { for User u in users ... }
Вам не все равно , если пользователи будут храниться в
List<T>
,Collection<T>
,Array<T>
или что - нибудь еще. Вам нужен толькоIEnumerable<T>
интерфейс.Если вам нужно иметь возможность добавлять, удалять или подсчитывать элементы в наборе, используйте коллекцию :
ICollection<User> users = new Collection<User>(); users.Add(new User());
Если вы заботитесь о порядке сортировки и хотите, чтобы порядок был правильным, используйте список :
IList<User> users = FetchUsers(db);
В виде диаграммы:
| Feature | IEnumerable<T> | ICollection<T> | IList<T> | |------------------------|----------------|----------------|----------| | Enumerating items | X | X | X | | | | | | | Adding items | | X | X | | Removing items | | X | X | | Count of items | | X | X | | | | | | | Accessing by index | | | X | | Removing by indexx | | | X | | Getting index of item | | | X |
List<T>
ИCollection<T>
вSystem.Collections.Generic
два класса , которые реализуют эти интерфейсы; но это не единственные классы:ConcurrentBag<T>
это заказанный мешок предметов (IEnumerable<T>
)LinkedList<T>
это сумка, в которой вам не разрешен доступ к элементам с помощью index (ICollection
); но вы можете произвольно добавлять и удалять элементы из коллекцииSynchronizedCollection<T>
в упорядоченной коллекции, где вы можете добавлять / удалять элементы по индексуТаким образом, вы можете легко изменить:
IEnumerable<User> users = new SynchronizedCollection<User>(); SaveEveryUser(users);
tl; dr
Выберите нужную вам концепцию , затем используйте соответствующий класс.
источник
ICollection<T>
иIList<T>
. Различные конкретные реализации могут вести себя по-разному. Например, если вы получаете доступ к aList<T>
через егоIEnumerable<T>
интерфейс, то у вас нет возможности добавлять, удалять, сортировать или подсчитывать элементы в списке.List<T>
предназначен для внутреннего использования в коде приложения. Вам следует избегать написания общедоступных API, которые принимают или возвращаютList<T>
(рассмотрите возможность использования вместо этого суперкласса или интерфейса коллекции).Collection<T>
служит базовым классом для пользовательских коллекций (хотя его можно использовать напрямую).Рассмотрите возможность использования
Collection<T>
в своем коде, если нет конкретных функций,List<T>
которые вам нужны.Выше приведены лишь рекомендации.
[Адаптировано из: Руководство по разработке каркаса, второе издание]
источник
Dictionary<string, List<string>>
для возвратаList<string>
- это нормально, поскольку состояние словаря инкапсулирует только идентификаторы списков в нем, а не их содержимое.List<T>
- это очень часто встречающийся контейнер, потому что он очень универсален (с множеством удобных методов, таких какSort
,Find
и т. д.), но не имеет точек расширения, если вы хотите переопределить какое-либо поведение (например, отметьте элементы на вставке).Collection<T>
является оболочкой для любогоIList<T>
(по умолчаниюList<T>
) - он имеет точки (virtual
методы) расширения , но не так много методов поддержки, какFind
. Из-за косвенного обращения он немного медленнееList<T>
, но ненамного.С LINQ дополнительные методы
List<T>
становятся менее важными, поскольку LINQ-to-Objects имеет тенденцию предоставлять их в любом случае ... напримерFirst(pred)
,OrderBy(...)
и т. Д.источник
Список быстрее.
Например
private void button1_Click(object sender, EventArgs e) { Collection<long> c = new Collection<long>(); Stopwatch s = new Stopwatch(); s.Start(); for (long i = 0; i <= 10000000; i++) { c.Add(i); } s.Stop(); MessageBox.Show("collect " + s.ElapsedMilliseconds.ToString()); List<long> l = new List<long>(); Stopwatch s2 = new Stopwatch(); s2.Start(); for (long i = 0; i <= 10000000; i++) { l.Add(i); } s2.Stop(); MessageBox.Show("lis " + s2.ElapsedMilliseconds.ToString()); }
на моей машине
List<>
почти в два раза быстрее.редактировать
Я не могу понять, почему люди голосуют против этого. И на моей рабочей машине, и на моей домашней машине код List <> на 80% быстрее.
источник
Список представляет собой коллекцию, в которой важен порядок элементов. Он также поддерживает методы сортировки и поиска. Коллекция - это более общая структура данных, которая делает меньше предположений о данных, а также поддерживает меньше методов для управления ими. Если вы хотите предоставить настраиваемую структуру данных, вам, вероятно, следует расширить коллекцию. Если вам нужно манипулировать данными без раскрытия структуры данных, список, вероятно, будет более удобным способом.
источник
Это один из тех вопросов аспирантуры. Коллекция T - своего рода абстрактная; может быть реализация по умолчанию (я не парень .net / c #), но коллекция будет иметь базовые операции, такие как добавление, удаление, итерация и т. д.
Список T подразумевает некоторые особенности этих операций: добавление должно занимать постоянное время, удаление должно занимать время, пропорциональное количеству элементов, getfirst должно быть постоянным временем. В общем, список является разновидностью коллекции, но коллекция не обязательно является разновидностью списка.
источник
Хансельман говорит : «
Collection<T>
выглядит как список, и у него даже естьList<T>
внутренний. КАЖДЫЙ единственный метод делегирует внутреннемуList<T>
. Он включает защищенное свойство, которое предоставляетList<T>
.»РЕДАКТИРОВАТЬ:
Collection<T>
не существует в System.Generic.Collections .NET 3.5. Если вы переходите с .NET 2.0 на 3.5, вам нужно будет изменить код, если вы используете многоCollection<T>
объектов, если я не упускаю что-то очевидное ...РЕДАКТИРОВАТЬ 2:
Collection<T>
теперь находится в пространстве имен System.Collections.ObjectModel в .NET 3.5. В файле справки сказано следующее:«Пространство имен System.Collections.ObjectModel содержит классы, которые могут использоваться как коллекции в объектной модели многоразовой библиотеки. Используйте эти классы, когда свойства или методы возвращают коллекции».
источник
Все эти интерфейсы являются наследниками
IEnumerable
, и вы должны убедиться, что понимаете. Этот интерфейс в основном позволяет использовать класс в операторе foreach (в C #).ICollection
- это самый простой из перечисленных вами интерфейсов. Это перечислимый интерфейс, который поддерживает a,Count
и на этом все.IList
есть все, чтоICollection
есть, но он также поддерживает добавление и удаление элементов, получение элементов по индексу и т. д. Это наиболее часто используемый интерфейс для «списков объектов», который, насколько мне известно, расплывчатый.IQueryable
- это перечисляемый интерфейс, поддерживающий LINQ. Вы всегда можете создатьIQueryable
из списка IList и использовать LINQ to Objects, но вы также можете найти егоIQueryable
для отложенного выполнения операторов SQL в LINQ to SQL и LINQ to Entities.IDictionary
это другое животное в том смысле, что это отображение уникальных ключей к значениям. Он также перечислим, поскольку вы можете перечислять пары ключ / значение, но в остальном он служит другой цели, чем другие, которые вы указали.источник
Согласно MSDN, List (Of T) .Add - это «операция O (n)» (когда «Capacity» превышена), а Collection (Of T) .Add - всегда «операция O (1)». Это было бы понятно, если бы List был реализован с использованием массива и коллекции связанного списка. Однако, если бы это было так, можно было бы ожидать, что Collection (Of T) .Item будет «операцией O (n)». Но - это - нет !?! Collection (Of T) .Item - это «операция O (1)», как и List (Of T) .Item.
Вдобавок к этому, сообщение "tuinstoel" "29 декабря '08 в 22:31" выше утверждает, что тесты скорости показывают List (Of T) .Add, чтобы быть быстрее, чем Collection (Of T) .Add, который я воспроизвел с помощью Длинные и струнные. Хотя я получил только ~ 33% быстрее по сравнению с его заявленными 80%, согласно MSDN, должно было быть наоборот и в "n" раз!?!
источник
Оба реализуют одни и те же интерфейсы, поэтому они будут вести себя одинаково. Возможно, они по-другому реализованы внутри, но это нужно будет проверить.
Единственные реальные различия, которые я вижу, - это пространства имен и тот факт, который
Collection<T>
отмечен значкомComVisibleAttribute(false)
, поэтому код COM не может его использовать.источник
В дополнение к другим ответам я составил краткий обзор общих возможностей списков и коллекций. Коллекция - это ограниченное подмножество Списка:
* = присутствует o = частично присутствует Коллекция свойств / методов <T> Список <T> ----------------------------------------------
Add() * * AddRange() * AsReadOnly() * BinarySearch() * Capacity * Clear() * * Contains() * * ConvertAll() * CopyTo() o * Count * * Equals() * * Exists() * Find() * FindAll() * FindIndex() * FindLast() * FindLastIndex() * ForEach() * GetEnumerator() * * GetHashCode() * * GetRange() * GetType() * * IndexOf() o * Insert() * * InsertRange() * Item() * * LastIndexOf() * New() o * ReferenceEquals() * * Remove() * * RemoveAll() * RemoveAt() * * RemoveRange() * Reverse() * Sort() * ToArray() * ToString() * * TrimExcess() * TrueForAll() *
источник