Uso de IReadOnlyCollection en lugar de IEnumerable para los parámetros para evitar una posible enumeración múltiple

Mi pregunta está relacionada con esta relacionada con el uso de IEnumerable vs IReadOnlyCollection .

Yo también siempre he usado IEnumerable para exponer colecciones como tipos y parámetros de retorno porque se beneficia de ser inmutable y de ejecución perezosa.

Sin embargo, estoy cada vez más preocupado por la proliferación de lugares en mi código donde debo enumerar un parámetro para evitar la posible advertencia de enumeración múltiple que ReSharper da. Entiendo por qué ReSharper sugiere esto, y estoy de acuerdo con el código que sugiere (a continuación) para garantizar la encapsulación (es decir, no hay suposiciones sobre la persona que llama).

  Foo[] arr = col as Foo[] ?? col.ToArray(); 

Sin embargo, encuentro que la repetitividad de este código es contaminante, y estoy de acuerdo con algunas fonts en que IReadOnlyCollection es una mejor alternativa, en particular los puntos IReadOnlyCollection en este artículo , que dice:

Últimamente, he estado considerando los méritos y desventajas de devolver IEnumerable .

En el lado positivo, es tan mínimo como se obtiene con una interfaz, por lo que te deja como autor de métodos más flexibilidad que comprometiéndote con una alternativa más pesada como IList o ( heaven forbid ) una matriz.

Sin embargo, como lo describí en el último post , un IEnumerable devuelve a los llamadores a violar el principio de sustitución de Liskov . Es demasiado fácil para ellos usar métodos de extensión LINQ como Last() y Count() , cuya semántica IEnumerable no promete.

Lo que se necesita es una mejor manera de bloquear una colección devuelta sin hacer tan notorias las tentaciones. (Recuerdo que Barney Fife aprendió esta lección de la manera más difícil).

Ingrese IReadOnlyCollection , nuevo en .NET 4.5. Agrega solo una propiedad a IEnumerable : la propiedad Count . Al prometer un recuento, usted asegura a sus interlocutores que su IEnumerable realmente tiene un término. Luego pueden usar los métodos de extensión LINQ como Last() con una conciencia limpia.

Sin embargo, como el observador puede haber notado, este artículo solo habla sobre el uso de IReadOnlyCollection para los tipos de devolución. Mi pregunta es, ¿los mismos argumentos se aplicarían igualmente al uso de parámetros también? Cualquier pensamiento teórico o comentario sobre esto también sería apreciado.

De hecho, estoy pensando que una regla general para usar IReadOnlyCollection sería donde podría haber una enumeración múltiple posible (con respecto a la advertencia ReSharper) si se IEnumerable . De lo contrario, utilice IEnumerable .

Habiendo reflexionado sobre esto más a fondo, he llegado a la conclusión, basado en el artículo que mencioné en mi pregunta, de que está bien usar IReadOnlyCollection como parámetro, pero solo en las funciones en las que definitivamente se enumerará. Si la enumeración es condicional en función de otros parámetros, el estado del objeto o el flujo de trabajo, entonces se debe pasar como IEnumerable para que la evaluación perezosa esté asegurada semánticamente.