Мой вопрос связан с этим вопросом об использовании IEnumerable<T>
vs IReadOnlyCollection<T>
.
Я также всегда использовал IEnumerable<T>
чтобы выставлять коллекции как возвращаемые типы и параметры, так как он выигрывает от неизменности и ленивости.
Тем не менее, меня все больше беспокоит распространение мест в моем коде, где я должен перечислить параметр, чтобы избежать возможного предупреждения о множественном перечислении, которое дает ReSharper. Я понимаю, почему ReSharper предлагает это, и я согласен с кодом, который он предлагает (ниже), чтобы обеспечить инкапсуляцию (т.е. Никаких предположений о вызывающем абоненте).
Foo[] arr = col as Foo[] ?? col.ToArray();
Тем не менее, я нахожу повторяемость этого кода загрязняющим, и я согласен с некоторыми источниками в том, что IReadOnlyCollection<T>
- лучшая альтернатива, особенно точки, сделанные в этой статье, в которой говорится:
В последнее время я рассматривал достоинства и недостатки возврата
IEnumerable<T>
.С положительной стороны он примерно такой же минимальный, как и интерфейс, поэтому он оставляет вас в качестве автора метода большей гибкостью, чем перенос на более тяжелую альтернативу, такую как
IList<T>
или (не дай бог) массив.Однако, как я изложил в последнем сообщении, возврат
IEnumerable<T>
побуждает вызывающих абонентов нарушать Принцип замещения Лискова. Слишком просто для них использовать методы расширения LINQ, такие какLast()
иCount()
, чья семантикаIEnumerable<T>
не обещает.Что нужно, это лучший способ заблокировать возвращенную коллекцию, не делая таких соблазнов столь выдающимися. (Мне вспоминается, что Барни Файф усвоил этот урок).
Введите
IReadOnlyCollection<T>
, новый в.NET 4.5. Он добавляет только одно свойство кIEnumerable<T>
: свойствоCount
. Пообещав подсчет, вы заверяете своих абонентов, что у вашегоIEnumerable<T>
действительно есть конечная точка. Затем они могут использовать методы расширения LINQ, такие какLast()
с чистой совестью.
Однако, как заметил наблюдатель, в этой статье говорится об использовании IReadOnlyCollection<T>
для возвращаемых типов. Мой вопрос в том, будут ли одинаковые аргументы одинаково применимы и к его использованию для параметров? Любые теоретические мысли или комментарии по этому вопросу также будут оценены.
На самом деле, я думаю, что общее правило для использования IReadOnlyCollection<T>
будет там, где будет возможно множественное перечисление (vis- à -vis предупреждение ReSharper), если используется IEnumerable<T>
. В противном случае используйте IEnumerable<T>
.