правило, которое я использую: никогда не используйте неконтролируемые исключения! (или когда Вы не видите пути вокруг этого)
существуют очень веские доводы в пользу противоположного: Никогда не используйте контролируемые исключительные ситуации. Я отказываюсь стать на сторону в дебатах, но там, кажется, общее согласие, что представляющий контролируемые исключительные ситуации было неправильное решение задним числом. Не стреляйте в средство рассылки и обращайтесь к те аргументы .
Ну, List
реализует IEnumerable
... в основном IEnumerable
- это просто последовательность пунктов. Вы можете прочитать его, и все.
List
- это изменяемая коллекция - вы можете добавлять в нее, удалять из нее, сортировать и т. Д. Сама по себе она более гибкая, но IEnumerable
позволяет использовать один и тот же код для работы с любой реализацией (массивы, связанные списки, списки, итераторы, возвращаемые из методов, использующих операторы yield
и т. Д.).
IEnumerable
- это более общий интерфейс, поэтому вы можете заменить все, что реализует этот интерфейс для своей операции. Если у вас есть этот метод:
public void DoSomething(IEnumerable<T> enumerable) {
}
Он будет работать с массивами, коллекциями, списками, словарями и всем остальным, что реализует интерфейс.
Если вы укажете, что объект является List
, метод будет работать только с объектами List
или экземплярами, которые унаследованы от него.
Преимущество использования List
состоит в том, что списки имеют гораздо больше функций, чем перечисляемые. Если вам нужны эти функции (вставка, поиск, преобразование и многое другое), List
или IList
более подходят.
Самыми большими преимуществами List
перед IEnumerable
являются следующие
Первые 2 легко сделать и на IEnumerable
, но вы не можете гарантировать скорость O (1). В случае с Count вы даже не можете гарантировать настоящий ответ, поскольку IEnumerable
может легко представлять бесконечные списки.
Список предоставляет дополнительные методы по сравнению с IEnumerable. Вы не можете добавить вставку или удалить с помощью IEnumerable, но можете с помощью List.
IEnumerable следует использовать, когда вы планируете перебирать только данные. Это дает вам преимущество перед IList, потому что вам не нужно загружать все данные сразу для доступа к данным, вам просто нужно иметь возможность получить следующую запись через перечислитель. IEnumerable также является интерфейсом, поэтому вы можете «скрыть» тип фактического объекта, содержащего список данных, массив и т. Д.
Если вам нужна только функциональность, представленная и реализованная в IEnumerable
, вам следует пойти с этим. Альтернативой является IEnumerable
, если вы хотите иметь возможность перебирать объекты, реализующие интерфейс IFoo
. Однако если вам требуются такие свойства, как Count
и такие, что List
предоставляет доступ, вам следует пойти на это. Найдите наименьший общий знаменатель и следуйте ему, так как он делает ваши методы более универсальными и с ними легче работать.
IEnumerable имеет чистый доступ только для чтения и семантика «перечисляемая» или «запрашиваемая». Со списком похоже, что вы позволяете кому угодно изменять его :).
Джон Скит и другие предложили хороший обзор функциональности List по сравнению с IEnumerable, поэтому я решил заполнить вторую половину вопроса: «Каковы преимущества использования IEnumerable над списком? ".
Во-первых, IEnumerable предоставляет более общий контракт для представления набора вещей, которые вы можете перебирать, и, следовательно, позволяет вам придерживаться принципа наименьших привилегий . Другими словами, IEnumerable должен быть предпочтительнее его производных типов, где перечисление - единственное поведение, которое необходимо предоставить для текущей задачи. Это полезно, потому что раскрытие информации и / или поведения без необходимости открывает ваш API для возможного непреднамеренного использования, которое может создать проблему безопасности или может вызвать непреднамеренную связь между вашим API и его потребителями.
Во-вторых, IEnumerable - это абстракция для перечисления, тогда как List - одна реализация этой абстракции. Следуя рекомендациям Шаблоны проектирования - элементы объектно-ориентированного программного обеспечения многократного использования , программирование на абстракции над реализациями помогает сделать приложения более устойчивыми к изменениям, позволяя изменять реализации позже, не влияя на объем кода. Если вам действительно нужно поведение списка, вы должны напрямую предоставлять IList, а не List.