Я играю с C # для Windows и ASP.net MVC в течение некоторого времени. Но я все еще неясен в некоторых областях. Я пытаюсь понять основное различие между проблемами производительности и использованием и обменом подобными видами интерфейсов универсальных коллекций .
Какова основная разница между IEnumerable<T>
, ICollection<T>
, List<T>(Class)
?
Я, кажется, использую и обмениваю их, не видя проблем в моих приложениях. Кроме того, есть ли еще подобные общие коллекции, подобные этим, которые можно заменить этими тремя?
c#
generics
interfaces
Панкадж Упадхяй
источник
источник
Ответы:
List <T> является классом и реализует интерфейсы ICollection <T> и IEnumerable <T> . Кроме того, ICollection <T> расширяет интерфейс IEnumerable <T>. Они не являются взаимозаменяемыми, по крайней мере, не со всех точек зрения.
Если у вас есть List <T>, вы гарантируете, что этот объект реализует методы и свойства, необходимые для реализации интерфейсами ICollection <T> и IEnumerable <T>. Компилятор знает это, и вам разрешено приводить их «вниз» либо к ICollection <T>, либо к IEnumerable <T> неявно. Однако, если у вас есть ICollection <T>, вы должны сначала явно проверить в своем коде, является ли это List <T> или что-то еще, возможно, Dictionary <T> (где T - KeyValuePair ), прежде чем привести его к тому, что вы желание.
Вы знаете, что ICollection расширяет IEnumerable, поэтому вы можете преобразовать его в IEnumerable. Но если у вас есть только IEnumerable, опять же вам не гарантируется, что это список. Может быть, но это может быть что-то еще. Следует ожидать недопустимого исключения приведения, если вы попытаетесь привести, например, List <T> к словарю <T>.
Таким образом, они не являются «взаимозаменяемыми».
Кроме того, существует множество универсальных интерфейсов, посмотрите, что вы можете найти в пространстве имен System.Collections.Generic .
Отредактируйте: в отношении вашего комментария нет абсолютно никакого снижения производительности, если вы используете List <T> или один из интерфейсов, которые он реализует. Вам все еще нужно будет создать новый объект, посмотрите следующий код:
list , myColl и myEnum указывают на один и тот же объект. Независимо от того, объявляете ли вы его как List, ICollection или IEnumerable, я все еще требую, чтобы программа создала List. Я мог бы написать это:
myColl , во время выполнения все еще список.
Тем не менее , это самый важный момент ... чтобы уменьшить связь и повысить удобство сопровождения, вы всегда должны объявлять свои переменные и параметры метода, используя наименьший возможный для вас знаменатель, будь то интерфейс, абстрактный или конкретный класс.
Представьте, что единственное, что нужно методу «PerformOperation», это перечислить элементы, выполнить некоторую работу и выйти, в этом случае вам не нужно больше сотни методов, доступных в List <T>, вам нужно только то, что доступно в IEnumerable <T >, поэтому должно применяться следующее:
Делая это, вы и другие разработчики знаете, что этот метод может быть передан любому объекту класса, реализующего интерфейс IEnumerable <T>. Это может быть List, Dictionary или пользовательский класс коллекции, написанный другим разработчиком.
Если, наоборот, вы указываете, что вам явно нужен конкретный List <T> (и хотя в реальной жизни это редко бывает, это все же может произойти), вы и другие разработчики знаете, что это должен быть либо List, либо другой конкретный класс, наследующий из списка.
источник
IList
а неList
в объявлении метода.List<>
определенная функциональность, например.AddRange()
. ЭтоIList<>
не разоблачает это.Взгляните на страницы MSDN для ICollection и IEnumerable .
В очень абстрактных терминах я так думаю об этих типах.
IEnumerable - это все, что может быть перечислено, то есть повторено. Это не обязательно означает «коллекцию»; например, IQueryable реализует IEnumerable, и это не коллекция, а то, что может быть запрошено для возврата объектов. Для реализации IEnumerable объект должен иметь возможность возвращать объект только при запросе. Я мог бы сказать, что у меня есть множество задач, которые я собираюсь выполнить сегодня (это не список, потому что я не записал и не сформулировал его, но я мог бы сказать вам, что я собираюсь сделать сейчас, и если бы вы спросили «а потом?», я бы смог рассказать вам следующее задание).
ICollection более конкретна, чем IEnumerable. Ключевое отличие состоит в том, что Коллекция знает, сколько предметов она содержит; чтобы определить, сколько элементов в Enumerable, вы эффективно просматриваете и подсчитываете их:
Как правило, коллекция - это то, что уже знает, где находятся все ее элементы, и ей не нужно будет искать и генерировать их, когда вы их запрашиваете. Это больше ... бетон, чем перечисляемый.
На мой взгляд, разница между перечисляемым и коллекцией намного больше, чем разница между коллекцией и списком. На самом деле, я изо всех сил пытаюсь придумать практическую разницу между коллекцией и списком, но я считаю, что список предоставляет лучшие методы для поиска и упорядочения.
Другие виды коллекций включают в себя
Queue
иStack
, а такжеDictionary
.Имена этих типов весьма полезны - вы можете представить очередь и стек в качестве их реальных аналогов и рассмотреть различия, которые могут у вас быть в списке.
источник
List
ЭтоICollection
, ноICollection
не всегдаList
(Queue
,Stack
,Dictionary
...)Queue<int> queue = (Queue<int>)list;
брошуInvalidCastException
когдаlist
не открываетсяQueue<int>
. Разница между очередью и списком выходит за рамки этого вопроса.IQueryable:
запрос не выполняется до тех пор, пока он действительно не перебирает элементы, возможно, с помощью .ToList ()
IEnumerable:
форвардный список предметов. Вы не можете получить "пункт 4", не пройдя пункты 0-3. список только для чтения, вы не можете добавить или удалить из него. Все еще может использовать отложенное выполнение.
IList:
произвольный доступ к полному списку полностью в памяти поддерживает добавление и удаление
ICollection:
Находится между IEnumerable и IList. Что «лучше» зависит от ваших требований. Обычно, хотя IEnumerable «достаточно хорош», если вы хотите отображать только элементы. По крайней мере, всегда используйте общий вариант.
источник