Usar IReadOnlyCollection<T>
o IReadOnlyList<T>
en la firma del método en lugar de IEnumerable<T>
, tiene la ventaja de hacer explícito que es posible que deba verificar el recuento antes de iterar, o iterar varias veces por alguna otra razón.
Sin embargo, tienen un gran inconveniente que causará problemas si intentas refactorizar tu código para usar interfaces, por ejemplo, para que sea más comprobable y amigable para el proxy dinámico. El punto clave es que IList<T>
no hereda deIReadOnlyList<T>
, y de manera similar para otras colecciones y sus respectivas interfaces de solo lectura. (En resumen, esto se debe a que .NET 4.5 quería mantener la compatibilidad ABI con versiones anteriores. Pero ni siquiera aprovecharon la oportunidad para cambiar eso en .NET core ) .
Esto significa que si obtienes un IList<T>
de alguna parte del programa y quieres pasarlo a otra parte que espera un IReadOnlyList<T>
, ¡no puedes! Sin embargo, puede pasar un IList<T>
como unIEnumerable<T>
.
Al final, IEnumerable<T>
es la única interfaz de solo lectura compatible con todas las colecciones .NET, incluidas todas las interfaces de colección. Cualquier otra alternativa volverá a morderte cuando te des cuenta de que te has bloqueado de algunas opciones de arquitectura. Por lo tanto, creo que es el tipo adecuado para usar en las firmas de funciones para expresar que solo desea una colección de solo lectura.
(Tenga en cuenta que siempre puede escribir un IReadOnlyList<T> ToReadOnly<T>(this IList<T> list)
método de extensión que convierta simples si el tipo subyacente admite ambas interfaces, pero debe agregarlo manualmente en todas partes al refactorizar, donde IEnumerable<T>
siempre es compatible).
Como siempre, esto no es absoluto, si está escribiendo un código pesado en la base de datos donde la enumeración múltiple accidental sería un desastre, es posible que prefiera una compensación diferente.