¿Cuál es el beneficio de usar List sobre IEnumerable ?

¿O al revés?

Yo uso listas genéricas todo el tiempo. Pero ocasionalmente escucho sobre IEnumerables, y honestamente no tengo ni idea (hoy) de para qué son y por qué debo usarlos. Entonces, a riesgo de tener algo en la red para siempre proclamar mi ignorancia, publico humildemente esta pregunta.

Bueno, List implementa IEnumerable … básicamente IEnumerable es solo una secuencia de elementos. Puedes leerlo, y eso es todo.

List es una colección mutable: puede agregarla, eliminarla, ordenarla, etc. Es más flexible en sí misma, pero IEnumerable permite usar el mismo código para trabajar con cualquier implementación (arreglos, enlaces listas, listas, iteradores devueltos de métodos que usan declaraciones de yield , etc.).

IEnumerable es una interfaz más general, por lo que puede sustituir cualquier cosa que implemente esa interfaz para su operación. Si tienes este método:

 public void DoSomething(IEnumerable enumerable) { } 

Funcionará en matrices, colecciones, listas, diccionarios y cualquier otra cosa que implemente la interfaz.

Si especifica que el objeto es una List , el método solo funcionará en List objetos o instancias de List que heredan de él.

La ventaja de usar la List es que las listas tienen muchas más características que los enumerables. Cuando necesite esas funciones (inserción, búsqueda, conversión y muchas más), List o IList es más apropiado.

John Skeet y otros han ofrecido una buena sinopsis de la funcionalidad de Lista sobre IEnumerable, así que pensé que completaría la otra mitad de la pregunta que es “¿Cuáles son los beneficios de usar IEnumerable sobre Lista?”.

Primero, IEnumerable proporciona un contrato más genérico para representar una colección de cosas que puede repetir y, por lo tanto, le permite adherirse al Principio de privilegio mínimo . En otras palabras, IEnumerable debe preferirse a sus tipos derivados, donde la enumeración es el único comportamiento que debe exponerse para la tarea en cuestión. Esto es beneficioso porque exponer información y / o comportamiento innecesariamente abre su API a posibles usos no deseados que pueden plantear un problema de seguridad o pueden causar un acoplamiento no deseado entre su API y sus consumidores.

Segundo, IEnumerable es una abstracción para la enumeración, mientras que List es una implementación de esa abstracción. Siguiendo la guía de Patrones de diseño – Elementos de software orientado a objetos reutilizables , la progtwigción a abstracciones sobre implementaciones ayuda a hacer que las aplicaciones sean más resistentes a los cambios al permitir que las implementaciones se cambien más adelante sin afectar el código consumidor. Si necesita un comportamiento de lista, debe exponer IList en lugar de Listar directamente.

Las mayores ventajas de List sobre IEnumerable son las siguientes

  1. Acceso aleatorio
  2. Conde propiedad
  3. Método forEach
  4. Mutabilidad

Los primeros 2 también son fáciles de hacer en IEnumerable pero no se puede garantizar la velocidad O (1). En el caso de Count, ni siquiera puede garantizar una respuesta real, ya que IEnumerable puede representar fácilmente listas infinitas.

Lista proporciona métodos adicionales sobre IEnumerable. No puede agregar insertar o eliminar con IEnumerable, pero puede hacerlo con Lista.

IEnumerable se debe usar cuando planea recorrer en bucle solo los datos. Le da una ventaja sobre IList, porque no tiene que cargar todos los datos a la vez para pasar el acceso a los datos, solo tiene que poder obtener el siguiente registro a través del enumerador. IEnumerable también es una interfaz, por lo que puede “ocultar” el tipo del objeto real que contiene la lista de datos, la matriz, etc.

Si solo necesita la funcionalidad expuesta e implementada en IEnumerable , debe ir con eso. Una alternativa es IEnumerable where T : IFoo si desea poder iterar sobre objetos que implementa la interfaz IFoo . Sin embargo, si usted requiere propiedades como Count y las que expone la List , debe hacerlo. Encuentre el mínimo común denominador e ir con eso, ya que hace que sus métodos sean más versátiles y más fáciles de trabajar.

IEnumerable tiene una semántica limpia de solo lectura y ‘enumerable’ o ‘queriable’. Con List parece que permites que alguien lo modifique :).

Una ventaja para IEnumerable que aún no se ha mencionado: la contraprestación. Una rutina que espera un IEnumerable (Of Car) será perfectamente feliz si se le da un IEnumerable (Of HondaCivic), lo que a su vez significa que estaría contento con un IList (Of HondaCivic). Por el contrario, una rutina que espera un IList (Of Car) no se satisfará con un IList (de HondaCivic). Si Microsoft IList derivara de una interfaz IReadableByIndex de solo lectura, entonces el código que esperaba un IReadableByIndex (Of Car) estaría perfectamente satisfecho con IReadableByIndex (Of HondaCivic), pero eso es agua debajo del puente.