Почему необходимо приводить те или иные множества к IEnumerable? И Как использовать IReadOnlyCollection?
1. Много где видел, что бест практис это приводить те или иные множества к IEnumerable, не совсем понимаю зачем и где вообще это нужно применять? К примеру у меня есть класс в котором использую List и мне нужно выдать его наружу. Мне выдавать IEnumerable или List всё ж. При передачи в методах коллекций, я так понимаю лучше именно абстракцию использовать(IEnumerable), чтобы не привязываться к List'у?
2. В каких ситуациях использовать IReadOnlyCollection и его производные??
Да просто пытаются защитить коллекцию от модификации. Когда ты на выходе получишь IEnumerable, то ты не изменить, не добавить элементы не можешь. Да и в большинстве случаев ты потом результат всё равно как последовательность обрабатываешь.
Принимай наиболее общие типы, отдавай наиболее специфичные.
На вход:
1) Если надо только перебрать элементы один раз то IEnumerable
2) Если нужен Count то IReadOnlyCollection
3) Если нужен индекс то IReadOnlyList
4) Если нужна запись, то ICollection или IList
На выход:
Наиболее специфичный тип. List<>, ReadOnlyCollection<>
Кстати, всегда смущал этот принцип. С первой частью утверждения я согласен, а вот второй выглядит сомнительно. В EF, например, все методы IEnumerable возвращают
mishkaaaaaa, второй помогает писать более производительный код. Вот если у вас есть на выходе List<> или Array и вы не владеете этим списком/массивом, но отдаете его как IEnumerable, то получатель что бы получить 10000 элемент должен:
а) перебрать 9999 элементов
б) нарушить типизацию и попробовать скастовать к IList<>
Конечно возвращая IEnumerable можно менять реализацию метода как хочешь. К примеру, вместо List<> возвращать HashSet<> и за абстракцией IEnumerable это будет не видно. Или вообще сделать реализацию через генераторы.
НО очень часто такая гибкость не нужна. А перфоманс лишним не бывает, в отличии от гибкости.
shai_hulud, перформанс нужен только тогда, когда есть проблемы с перформансом, ИМХО. Сколько задротил на проектах с перформансом - ни одного живого нет сейчас))) Я почти всегда List использую. В 95% случаев с головой хватает. А перформанс обычно улетает на какой-то сериализации.
Сергей Веремеенко, тоже удивляет, когда в разговорах про перфоманс упоминают такие вещи. Просадка производительности скорее всего будет в запросах к БД, работе с внешними API, сериализации, работе с файлами и пр. Не могу представить проект, где замена IEnumerable<> на IList<> дала бы заметный прирост
Сергей Веремеенко, Перфоманс нужен либам т.к. у либ всегда есть требование - "лучший перформанс за разумное время", он почти никогда не нужен продуктам т.к. там требования, в основном, про фичи. Так что не удивлен, что проекты про перфоманс мертвы. mishkaaaaaa, Там где есть БД, про перфоманс уже можно не говорить, его похоронили. И это не связано с самими БД, он умер в голове того, кто это проектировал. Все остальные описанные кейсы параллелизуются, пулятся и вызываются асинхронно.
Как можно просесть на коллекциях я описал пример выше. Ну, и конечно можно взять коллекция на 100к элементов, потом добавить сверху LINQ, сделать OrderBy, потом Where, и вернуть ее методу который внутри ее будет итерировать для поиска каждого элемента через ElementAt. Ведь ему вернули IEnumerable<>, а он хотел IList<>, а фичу программисту надо сдавать сегодня.
да фигня это все IEnumerable<T> нужен тогда и только тогда, когда нужны асинхроннные или ленивые вычисления, по тому что метод возвращающий IEnumerable<T>, имеет право возвращать не весь набор, а возвращать экземпляры T поштучно, вот так yield return (T)foo;
а вот уже эта фича, открывает много новых и интересных возможностей для параллельного программирования