Использование IReadOnlyCollection <T> вместо IEnumerable <T> для параметров, чтобы избежать возможного многократного перечисления
Мой вопрос связан сэтот относительно использованияIEnumerable<T>
против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>
было бы там, где было бы возможно многократное перечисление (по отношению к предупреждению ReSharper), еслиIEnumerable<T>
используется. В противном случае используйтеIEnumerable<T>
.