Обычно выбор зависит от того, к каким методам вам нужен доступ. В общем случае - IEnumerable<>
(MSDN: http://msdn.microsoft.com/en-us/library/system.collections.ienumerable.aspx ) для списка объектов, для которых требуется только итерация, ICollection<>
(MSDN: http: // msdn.microsoft.com/en-us/library/92t2ye13.aspx ) для списка объектов, которые необходимо перебрать и изменить, List<>
для списка объектов, которые необходимо перебрать, изменить, отсортировать и т. д. (см. здесь полный список: http://msdn.microsoft.com/en-us/library/6sh2ey19.aspx ).
С более конкретной точки зрения, ленивая загрузка играет с выбором типа. По умолчанию свойства навигации в Entity Framework поставляются с отслеживанием изменений и являются прокси-серверами. Чтобы динамический прокси-сервер создавался как свойство навигации, виртуальный тип должен быть реализован ICollection
.
Свойство навигации, которое представляет конец отношения «многие», должно возвращать тип, реализующий ICollection, где T - это тип объекта на другом конце отношения. - Требования к созданию POCO-прокси MSDN
Подробнее об определении и управлении отношениями MSDN
List
должно быть намного лучше, да?List
. Хотя у него больше всего накладных расходов, он обеспечивает большую функциональность.private IEnumerable<int> _integers = new List<int> { 1, 2, 3 };
использует ту же память, что иprivate List<int> _integers = new List<int> { 1, 2, 3 };
List<T>
имеетGetEnumerator()
метод, отдельный от его реализацииIEnumerable<T>
, который возвращает изменяемый тип структурыList<T>.Enumerator
. В большинстве случаев этот тип даст немного лучшую производительность, чем автономный объект кучи. Компиляторы, которые используют перечислители утилитарного типа (как это делают и C #, и vb.net), могут воспользоваться этим при генерацииforeach
кода. Если методList<T>
приведен кIEnumrable<T>
передforeach
,IEnumerable<T>.GetEnumerator()
метод вернет объект, выделенный в куче , что сделает оптимизацию невозможной.ICollection<T>
используется потому, чтоIEnumerable<T>
интерфейс не позволяет добавлять элементы, удалять элементы или иным образом изменять коллекцию.источник
List<T>
инвентарьICollection<T>
.ICollection
способ не позволяет добавлять элементы, но все же является полезным дополнением к нему,IEnumerable<T>
поскольку он предоставляетCount
элемент, который обычно намного быстрее, чем перечисление всего. Обратите внимание, что еслиIList<Cat>
илиICollection<Cat>
передается в код, ожидающийIEnumerable<Animal>
,Count()
метод расширения будет быстрым, если он реализует неуниверсальныйICollection
, но не если он реализует только универсальные интерфейсы, так как типичныйICollection<Cat>
не будет реализовыватьICollection<Animal>
.Отвечая на ваш вопрос о
List<T>
:List<T>
это класс; указание интерфейса обеспечивает большую гибкость реализации. Лучший вопрос - почему бы и нетIList<T>
?Чтобы ответить на этот вопрос, рассмотрим, что
IList<T>
добавляетICollection<T>
: целочисленное индексирование, что означает, что элементы имеют некоторый произвольный порядок и могут быть получены с помощью ссылки на этот порядок. Это, вероятно, не имеет смысла в большинстве случаев, так как предметы, вероятно, нужно заказывать по-разному в разных контекстах.источник
Есть некоторые основные различия между ICollection и IEnumerable
Простая программа:
источник
Я помню это так:
IEnumerable имеет один метод GetEnumerator (), который позволяет читать значения в коллекции, но не записывать в нее. Большая часть сложности использования перечислителя позаботилась о нас для каждого оператора в C #. IEnumerable имеет одно свойство: Current, которое возвращает текущий элемент.
ICollection реализует IEnumerable и добавляет несколько дополнительных свойств, наиболее используемым из которых является Count. Универсальная версия ICollection реализует методы Add () и Remove ().
IList реализует как IEnumerable, так и ICollection и добавляет целочисленный индексный доступ к элементам (что обычно не требуется, так как упорядочение выполняется в базе данных).
источник
Основная идея использования
ICollection
- предоставить интерфейс для доступа только для чтения к некоторому конечному количеству данных. На самом деле у вас есть свойство ICollection.Count .IEnumerable
больше подходит для некоторой цепочки данных, где вы читаете до некоторой логической точки, некоторого условия, явно указанного потребителем, или до конца перечисления.источник
ICollection
только для чтения, покаICollection<T>
нет.Свойства навигации обычно определяются как виртуальные, чтобы они могли использовать определенные функции Entity Framework, такие как отложенная загрузка.
Если свойство навигации может содержать несколько объектов (как в отношениях «многие ко многим» или «один ко многим»), его тип должен быть списком, в который можно добавлять, удалять и обновлять записи, например, ICollection.
https://www.asp.net/mvc/overview/getting-started/getting-started-with-ef-using-mvc/creating-an-entity-framework-data-model-for-an-asp-net- MVC-приложения
источник
То, что я делал в прошлом, это объявлял мои коллекции внутренних классов, используя
IList<Class>
,ICollection<Class>
илиIEnumerable<Class>
(если статический список), в зависимости от того, придется ли мне выполнять какое-либо из следующих действий в методе в моем репозитории: перечислять, сортировать / упорядочивать или изменять , Когда мне просто нужно перечислить (и, возможно, отсортировать) объекты, я создаю временный шаблонList<Class>
для работы с коллекцией в методе IEnumerable. Я думаю, что эта практика будет эффективной только в том случае, если коллекция будет относительно небольшой, но в целом это может быть хорошей практикой, ИДК. Пожалуйста, поправьте меня, если есть доказательства того, почему это не будет хорошей практикой.источник
Давайте попробуем мыслить нестандартно с помощью / by логики и четко понимать эти три интерфейса в вашем вопросе:
Когда класс некоторого экземпляра реализует интерфейс System.Collection.IEnumerable, то, простыми словами, мы можем сказать, что этот экземпляр является и перечислимым, и итеративным, что означает, что этот экземпляр позволяет каким-то образом в одном цикле перейти / get / pass / пройти / перебрать все элементы и элементы, содержащиеся в этом экземпляре.
Это означает, что также возможно перечислить все элементы и элементы, которые содержит этот экземпляр.
Каждый класс, который реализует интерфейс System.Collection.IEnumerable, также реализует метод GetEnumerator, который не принимает аргументов и возвращает экземпляр System.Collections.IEnumerator.
Экземпляры интерфейса System.Collections.IEnumerator ведут себя очень похоже на итераторы C ++.
Когда класс некоторого экземпляра реализует интерфейс System.Collection.ICollection, то, простыми словами, мы можем сказать, что этот экземпляр представляет собой некоторую коллекцию вещей.
Универсальная версия этого интерфейса, то есть System.Collection.Generic.ICollection, является более информативной, поскольку этот универсальный интерфейс явно указывает тип объектов в коллекции.
Все это разумно, рационально, логично и имеет смысл, что интерфейс System.Collections.ICollection наследуется от интерфейса System.Collections.IEnumerable, поскольку теоретически каждая коллекция также является и перечислимой, и итеративной, и теоретически можно обойти все элементы и элементы. в каждой коллекции.
Интерфейс System.Collections.ICollection представляет конечную динамическую коллекцию, которая может изменяться, что означает, что существующие элементы могут быть удалены из коллекции, а новые элементы могут быть добавлены в ту же коллекцию.
Это объясняет, почему интерфейс System.Collections.ICollection имеет методы «Добавить» и «Удалить».
Поскольку экземпляры интерфейса System.Collections.ICollection являются конечными коллекциями, то слово «конечный» подразумевает, что каждая коллекция этого интерфейса всегда имеет конечное число элементов и элементов.
Свойство Count интерфейса System.Collections.ICollection предполагает возвращение этого числа.
Интерфейс System.Collections.IEnumerable не имеет этих методов и свойств, которые есть у интерфейса System.Collections.ICollection, поскольку он не имеет никакого смысла в том, что System.Collections.IEnumerable будет иметь эти методы и свойства, которые есть в интерфейсе System.Collections.ICollection.
Логика также гласит, что каждый перечисляемый и итеративный экземпляр не обязательно является коллекцией и не обязательно изменяем.
Когда я говорю «изменяемый», я имею в виду, что не следует сразу думать, что вы можете добавить или удалить что-то из того, что является и перечислимым, и итеративным.
Например, если я только что создал некоторую конечную последовательность простых чисел, то эта конечная последовательность простых чисел действительно является экземпляром интерфейса System.Collections.IEnumerable, потому что теперь я могу просмотреть все простые числа в этой конечной последовательности в одном цикле. и делайте все, что я хочу, с каждым из них, например, печатая каждый из них в окне консоли или на экране, но эта конечная последовательность простых чисел не является экземпляром интерфейса System.Collections.ICollection, потому что это не имеет смысла добавить составные числа к этой конечной последовательности простых чисел.
Кроме того, вы хотите, чтобы в следующей итерации было получено следующее ближайшее большее простое число к текущему простому числу в текущей итерации, если это так, вы также не хотите удалять существующие простые числа из этой конечной последовательности простых чисел.
Также вы, вероятно, захотите использовать, кодировать и записывать «возвращение дохода» в методе GetEnumerator интерфейса System.Collections.IEnumerable, чтобы получить простые числа и ничего не распределять в куче памяти, а затем назначить сборщик мусора (GC) обоим освободите и освободите эту память из кучи, поскольку это, очевидно, одновременно приводит к потере памяти операционной системы и снижает производительность.
Динамическое выделение и освобождение памяти в куче должно выполняться при вызове методов и свойств интерфейса System.Collections.ICollection, но не при вызове методов и свойств интерфейса System.Collections.IEnumerable (хотя интерфейс System.Collections.IEnumerable имеет только 1 метод и 0 свойств).
Согласно тому, что другие говорили на этой веб-странице переполнения стека, интерфейс System.Collections.IList просто представляет заказ коллекцию, которую можно и это объясняет, почему методы интерфейса System.Collections.IList работают с индексами в отличие от методов интерфейса System.Collections.ICollection.
Короче говоря, интерфейс System.Collections.ICollection не подразумевает, что его экземпляр можно заказать, но интерфейс System.Collections.IList подразумевает это.
Теоретически упорядоченное множество является частным случаем неупорядоченного множества.
Это также имеет смысл и объясняет, почему интерфейс System.Collections.IList наследует интерфейс System.Collections.ICollection.
источник