Pregunta ¿Qué interfaz debería devolver mi servicio? IQueryable, IList, IEnumerable?


Imagínese que tengo una capa SearchService que tiene un método para buscar todos los automóviles comenzando con una cierta cadena;

public static class Searcher{
    public IAnInterface<Car> CarsStartingWith(string startWith){
        //magic
    }
}

¿Qué interfaz debería usar mi servicio?
IQueryable puede representar una interfaz fluida en el resto de mi aplicación.
IEnumerable tiene el aspecto perezoso que lo acompaña.
IList es simplemente el más práctico.

Me gustaría que todos mis servicios devuelvan la misma interfaz para la coherencia hace que todo sea mucho más fácil.
ICollection podría ser una opción también, pero ofrece muy poco ...


9
2018-03-25 14:55


origen


Respuestas:


Si desea que todos sus servicios devuelvan la misma interfaz, probablemente apunte a IEnumerable<>.

Será fácil para sus interlocutores convertir a IQueryable o crea un List, si necesario:

IEnumerable<Car> cars = Searcher.CarsStartingWith("L");
var carsList = cars.ToList();
var queryableCars = cars.AsQueryable();

2
2018-03-25 15:07



yo elegiría IEnumerable porque tiene un lugar más central en el marco, brinda versatilidad a quienes lo necesitan y, al mismo tiempo, proporciona familiaridad a aquellos que todavía no se han metido en cosas como LINQ.


3
2018-03-25 14:57



Mi regla de oro es la siguiente:

Si alguna vez existe la posibilidad de que pueda tomar el algoritmo central de la rutina y refactorizarlo de forma que pueda usar rendimientos de rentabilidad, iré con IEnumerable <T>.

Por ejemplo, si mi implementación actual usa una matriz o una Lista <T> internamente, pero sé que, al menos teóricamente, puedo querer y ser capaz de volver a trabajar internamente para hacer una evaluación lenta, devolveré un IEnumerable < T>.

He descubierto que las ganancias de devolver IEnumerable <T> definitivamente valen la molestia de usarlo.

Sin embargo, si el algoritmo, por su propia naturaleza, va a necesitar evaluar completamente los resultados antes de regresar (raro, pero sucede), iré con un IList <T>. Básicamente, si ya lo estoy computando, lo devolveré. IList <T> implementa IEnumerable <T>, por lo que todos los casos de uso relacionados con LINQ siguen funcionando, pero pierde la evaluación perezosa. Si ya estoy obligado a evaluar por adelantado, eso no es un problema, sin embargo.

Raramente regreso IQueryable. La única vez que usaría esta interfaz es si estoy creando directamente una capa de acceso a datos consultable, o algo similar. La sobrecarga de usar esto es, en la mayoría de los casos, no vale la pena las ganancias.

Sin embargo, si su objetivo es usar siempre una sola interfaz (no necesariamente estoy de acuerdo con este objetivo), me quedaría con IEnumerable <T>.


3
2018-03-25 15:47



IQueryable tendría un requisito bastante pesado: no podría, por ejemplo, devolver una matriz.

Por lo general, para mí, la elección entre IEnumerable o IList generalmente termina siendo el que sea más fácil de implementar en el caso estándar.


2
2018-03-25 14:58



Respuesta corta: depende.

Respuesta más larga: devuelva el tipo más rico que su código de cliente va a necesitar. IList funciona en la mayoría de los casos si no necesita carga diferida. Todavía puede usar Linq para consultar contra un IList o IEnumerable. Si la carga lenta es un requisito, entonces vaya con IEnumerable o IQueryable.

Nota al margen: devolver la misma interfaz para todos los servicios puede parecer una meta noble, pero dados los diferentes patrones de uso del cliente, es posible que desee devolver diferentes interfaces.


2
2018-03-25 15:05



Siempre ve con IEnumerable a menos que tengas una razón seria para no hacerlo. Luego puede implementar el getter con yield return.

IQueryable es una olla de pescado totalmente diferente. No es algo que implemente casualmente como una alternativa a un contenedor típico en memoria.

Del resto, hay una gran diferencia entre IEnumerable y los demás: es de solo lectura.


2
2018-03-25 15:20



Si usa IQueryable como tipo de devolución, tiene una capa de servicio con abstracción con pérdida.


0
2018-03-14 10:42