2009-11-09 9 views
9

o al revés?¿Cuál es el beneficio de usar la Lista <T> sobre IEnumerable <T>?

Uso listas genéricas todo el tiempo. Pero también escucho ocasionalmente sobre IEnumerables, y honestamente no tengo ni idea (hoy) para qué son y por qué debería usarlos. Por lo tanto, a riesgo de tener algo en la red para siempre proclamando mi ignorancia, publico humildemente esta pregunta.

+0

¿Quiso decir IList ? –

+0

No. Estoy bastante seguro de que me refiero a la lista . –

Respuesta

16

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

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

+0

Dado que 'IEnumerable ' es inmutable, puede utilizar esta interfaz al devolver datos de su clase sabiendo que no se agregarán ni eliminarán elementos. Aunque el usuario todavía puede llamar a las funciones de mutación en los objetos que contiene _within_ el enumerable. –

+3

@Marcel: nota bastante cierto. La interfaz 'IEnumerable ' no contiene métodos para alterar la secuencia. La implementación concretada puede ser o no mutable. Si una firma de método dice que devuelve 'IEnumerable ' y el código devuelve 'List ', el código de llamada puede convertir fácilmente el objeto devuelto a 'List ' y alterar el contenido de la lista. Sin embargo, la firma * comunica que el resultado debe tratarse como de solo lectura *. –

+1

Todavía es posible devolverlo a 'IList ' en el sitio de la llamada, por lo que esto no es a prueba de balas. – recursive

6

IEnumerable<T> es una interfaz más general, por lo que puede sustituir todo lo que implemente esa interfaz para su funcionamiento. Si usted tiene este método:

public void DoSomething(IEnumerable<T> enumerable) { 
} 

Se trabajará en arrays, colecciones, listas, diccionarios, y cualquier otra cosa que implementa la interfaz.

Si especifica que el objeto es List<T>, el método solo funcionará en los objetos List<T> o instancias que hereden de él.

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

1

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

IEnumerable se debe utilizar cuando planea recorrer los datos solamente. Le da una ventaja sobre IList, ya que 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 es también una interfaz, por lo que puede "ocultar" el tipo del objeto real que contiene la lista de datos, etc. matriz

2

Las mayores ventajas de List<T> sobre IEnumerable<T> son los siguientes

  1. acceso aleatorio
  2. Conde propiedad
  3. método ParaCada
  4. mutabilidad

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

0

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

0

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

6

John Skeet y otros han ofrecido una buena sinopsis de la funcionalidad de List over IEnumerable, así que pensé en completar la otra mitad de la pregunta "¿Cuáles son los beneficios de usar IEnumerable over List?".

En primer lugar, IEnumerable proporciona un contrato más genérico para representar una colección de cosas que puede iterar y, por lo tanto, le permite adherirse al Principle of Least Privilege. En otras palabras, debe preferirse IEnumerable 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 involuntarios que pueden plantear un problema de seguridad o pueden causar un acoplamiento involuntario entre su API y sus consumidores.

En segundo lugar, 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 Design Patterns - Elements of Reusable Object-Oriented Software, la programación de abstracciones sobre implementaciones ayuda a hacer que las aplicaciones sean más resistentes al cambio al permitir que las implementaciones se modifiquen más tarde sin afectar el código de consumo. Si necesita un comportamiento de lista, debe exponer IList en lugar de List directamente.

+0

Excelente respuesta. Estás un poco retrasado en el juego, pero estoy totalmente de acuerdo. Aprendí mucho desde el pasado noviembre. :) –

+0

Pensé en opinar sobre la posteridad :) –

0

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

Cuestiones relacionadas