Usando IReadOnlyCollection <T> em vez de IEnumerable <T> para parâmetros para evitar possíveis enumerações múltiplas
Minha pergunta está relacionada aeste sobre o uso deIEnumerable<T>
vsIReadOnlyCollection<T>
.
Eu também sempre useiIEnumerable<T>
expor coleções como tipos e parâmetros de retorno porque se beneficia de ser imutável e executado com preguiça.
No entanto, estou ficando cada vez mais preocupado com a proliferação de locais no meu código, onde devo enumerar um parâmetro para evitar o possível aviso de enumeração múltipla que o ReSharper fornece. Entendo por que o ReSharper sugere isso e concordo com o código sugerido (abaixo) para garantir o encapsulamento (ou seja, sem suposições sobre o chamador).
Foo[] arr = col as Foo[] ?? col.ToArray();
No entanto, considero a repetitividade deste código poluente e concordo com algumas fontes queIReadOnlyCollection<T>
é uma alternativa melhor, principalmente os argumentosEste artigo, quais Estados:
Ultimamente, tenho considerado os méritos e deméritos de retornarIEnumerable<T>
.
No lado positivo, é quase o mínimo que uma interface obtém, portanto, deixa você como autor do método mais flexível do que se comprometer com uma alternativa mais pesada, comoIList<T>
ou (o céu proíbe) uma matriz.
No entanto, como descrevi emo último post, aIEnumerable<T>
retorno atrai os chamadores a violar oPrincípio da substituição de Liskov. É muito fácil para eles usar métodos de extensão LINQ comoLast()
eCount()
cuja semânticaIEnumerable<T>
não promete.
O que é necessário é uma maneira melhor de bloquear uma coleção retornada sem tornar essas tentações tão proeminentes. (Lembro-me de Barney Fife aprendendo esta lição da maneira mais difícil.)
EntrarIReadOnlyCollection<T>
, novo no .NET 4.5. Adiciona apenas uma propriedade aoIEnumerable<T>
: aCount
propriedade. Ao prometer uma contagem, você garante aos seus chamadores que seusIEnumerable<T>
realmente tem um término. Eles podem usar os métodos de extensão LINQ, comoLast()
com a consciência limpa.
No entanto, como o observador deve ter notado, este artigo fala apenas sobre o usoIReadOnlyCollection<T>
para tipos de retorno. Minha pergunta é: os mesmos argumentos se aplicariam igualmente ao uso para parâmetros também? Quaisquer pensamentos ou comentários teóricos sobre isso também serão apreciados.
Na verdade, estou pensando em uma regra geral para usarIReadOnlyCollection<T>
seria onde haveria possível enumeração múltipla (em relação ao aviso ReSharper) seIEnumerable<T>
é usado. Caso contrário, useIEnumerable<T>
.