Supongamos que tengo un método
public List<User> GetBatchOfUsers(IEnumerable<int> userIDs)
{
List<User> users = new List<User>();
// some database stuff
return users;
}
He leído que sería mejor devolver una interfaz (ya sea IList
o IEnumerable
) en lugar de devolver a List
. Algunos de los argumentos que escuché al respecto es que oculta datos y le da al desarrollador de API la flexibilidad de cambiar la representación interna de los datos en una fecha posterior.
Mi preocupación acerca de solo devolver un IEnumerable
es que pierdes funcionalidad, como el acceso aleatorio y la Count
propiedad.
Sé que aceptar un IEnumerable
parámetro tiene sentido, ya que le da al consumidor la mejor flexibilidad para enviar datos a mi método, el conjunto minimalista de requisitos para que el método funcione.
¿Cuál es la mejor práctica para el tipo de devolución?
c#
interfaces
class
Mateo
fuente
fuente
Respuestas:
En términos generales, puede comenzar con las interfaces y solo moverse para poner el tipo concreto como el tipo de retorno si descubre que usa los métodos adicionales con más frecuencia de lo esperado.
Bueno, si devuelve una interfaz, conservará más flexibilidad. Puede cambiar la implementación más tarde para devolver un tipo concreto diferente. Por otro lado, obviamente le da menos información a la persona que llama, por lo que es posible que no pueda realizar ciertas operaciones. (Por ejemplo: si regresa
List<T>
, la persona que llama puede usar ConvertAll, etc., lo cual no puede hacer si solo declara que regresaIList<T>
). En algunas situaciones, vale la pena especificar el tipo concreto.Con respecto al método Count u Sort, no hay interfaces de recopilación estándar para eso. Sin embargo, podría escribir un método de extensión para ordenar o contar cualquier IList.
fuente
Si necesita que su colección tenga una
Count
que pueda usarICollection<T>
, que es lo suficientemente general.fuente
Devuelve lo que es prudente para el método que está definiendo. ¿Lo que está haciendo es devolver una serie de elementos (el foco está en los elementos), o está devolviendo una colección de elementos (el foco está en la colección como un todo)? ¿Vale la pena permitir variaciones en la implementación de la colección? Si nunca tiene sentido usar un generador o
HashSet
simplemente usar elList
.fuente
Específico para el método de ejemplo: tiene razón en que regresar
IEnmuerable<T>
significaría que perdería la funcionalidadCount
y la indexación (aunque podría usar métodos LINQCount()
yElementAt()
, que se implementan de manera eficiente si el tipo en el que se usan realmente se implementaIList<T>
).Si regresa
IList<T>
, perdería alguna funcionalidad, pero la ganancia en general probablemente valga la pena.Pero aún mejor sería algo intermedio
IEnumerable<T>
yIList<T>
, porque lo más probable es que no tenga sentido que el consumidor mute la colección devuelta, pero sí tiene sentido que useCount
o indexe.En .Net 4.5, no es tal interfaz:
IReadOnlyList<T>
.fuente
IReadOnlyList
suena bien cuando puedo obtener VS2013, gracias!