Мой вопрос связан с этим относительно использования 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>
было бы там, где было бы возможно множественное перечисление (по отношению к предупреждению ReSharper), если используется IEnumerable<T>
. В противном случае используйте IEnumerable<T>
.
[NoEnumeration]
, ну, это просто атрибут, но там написаноIndicates that IEnumerable, passed as parameter, is not enumerated.
, он ничего не делает, но я использовал его, потому что это круто - person M.kazem Akhgary   schedule 21.12.2016IEnumerable
. Но мой вопрос шире, чем этот вариант использования, и больше о том, где перечисляетсяIEnumerable
. Является лиIReadOnlyCollection<T>
лучшей альтернативой в этих случаях по причинам, которые я упомянул (т. Е. По пунктам, сделанным в статье)? - person Neo   schedule 21.12.2016