¿Cuál es la diferencia entre IEnumerable
y Array
?
¿Cuál es la diferencia entre IList
y List
?
Estos parecen tener la misma función.
IEnumerable proporciona solo una funcionalidad mínima "iterable". Puedes recorrer la secuencia, pero eso es todo. Esto tiene desventajas, por ejemplo, es muy ineficiente contar elementos usando IEnumerable o para obtener el enésimo elemento, pero también tiene ventajas, por ejemplo, un IEnumerable podría ser una secuencia sin fin, como la secuencia de números primos.
Array es una colección de tamaño fijo con acceso aleatorio (es decir, puede indexar en ella).
La lista es una colección de tamaño variable (es decir, puede agregar y eliminar elementos) con acceso aleatorio.
IList es una interfaz que abstrae la funcionalidad de la lista (contar, agregar, eliminar, acceso al indexador) de las diversas clases concretas como List, BindingList, ObservableCollection, etc.
IEnumerable es una interfaz que permite la iteración a través de una colección de elementos (por ejemplo, a través de la palabra clave foreach).
Una matriz es intrínseca a .NET. Contiene elementos del mismo tipo, pero de tamaño fijo. Una vez que crea una matriz con x elementos, no puede crecer ni reducirse.
IList define la interfaz para una lista y también implementa IEnumerable.
List implementa la interfaz IList; es un tipo concreto de lista.
La diferencia entre las listas de .NET y las matrices es que a las listas se les pueden agregar elementos; crecen hasta ser lo suficientemente grandes como para contener todos los elementos necesarios. La lista almacena esto internamente en una matriz y, cuando la matriz ya no es lo suficientemente grande para contener todos los elementos, se crea una nueva matriz y los elementos se copian.
IList y las matrices implementan IEnumerable. Así es como funcionan las interfaces: las clases implementan el contrato y se comportan de manera similar y, como resultado, pueden tratarse de manera similar (usted sabe que la clase implementa IEnumerable, no necesita saber los cómo ni los por qué). Le sugiero que lea sobre interfaces y demás.
fuente
IEnumerable e IList son interfaces . Array y List son clases. Array implementa IEnumerable. List implementa IList que extiende IEnumerable.
Editar: como mencionó itowlson en un comentario, Array también implementa IList.
fuente
La generación de una colección IEnumerable es lenta. Ejemplo:
En el método Something, la llamada a GetTwoInts () no dará como resultado la ejecución del método GetTwoInts, ya que la enumeración nunca se repite.
fuente
twoInts
unaforeach
llamada otwoInts.ToList()
.IEnumerable
es una interfaz de propósito general que utilizan muchas clases, comoArray
,List
yString
para permitir que alguien itere sobre una colección. Básicamente, es lo que impulsa laforeach
declaración.IList
suele ser la forma en que expone las variables de tipoList
a los usuarios finales. Esta interfaz permite el acceso aleatorio a la colección subyacente.fuente
Para complementar las otras respuestas, tenga en cuenta que existe una diferencia de rendimiento entre
IList<T>
yList<T>
al ejecutar una declaración foreach.Esto se debe a que el objeto iterador devuelto por
List<T>.GetEnumerator
es un tipo de valor, mientras que el devuelto porIList<T>.GetEnumerator
es un tipo de referencia y, por lo tanto, requiere una asignación de memoria (consulte Enumerador del tipo de valor de la lista en c # ).En mi opinión,
IList<T>
no es una interfaz muy buena de todos modos. Por ejemplo, la llamadaAdd
can throw (consulte ¿Por qué la matriz implementa IList? ). Si necesita encapsulación, sería mejor usarIEnumerable<T>
oIReadOnlyList<T>
.fuente
Además de otras respuestas, comprender las diferencias entre Enumerable y List / Array cuando se usa LINQ puede tener un gran impacto en el rendimiento. En resumen, Enumerable se puede percibir como un generador de consultas, mientras que List / Array es el resultado de la consulta.
En el contexto de LINQ to SQL usando EntityFramework, el primero simplemente está construyendo la consulta SQL sin ejecutarla en la base de datos ni cargar ningún dato en la memoria, mientras que el segundo es lo opuesto. Es por eso que aplazaríamos la llamada
.ToList()
hasta que la necesitemos en la memoria para realizar la lógica empresarial.En otro contexto, la expresión LINQ que devuelve IEnumerable pospondrá la ejecución hasta que
.ToList()
se llame. Considere el ejemplo siguiente:En el primer ejemplo, dos
.Where()
se "agregan" y se ejecutan juntos al final cuando.ToList()
se llama con el elemento " A " pasando primero por la tubería y luego el elemento " B ", por lo que se ve " AABB " en la salida, mientras que en el segundo ejemplo, el.Where()
se ejecuta cada vez si llamamos.ToList()
inmediatamente después, por lo tanto, vemos " CD " y luego " CD " nuevamente, salida dos veces. Por lo tanto, cada vez que un Enumerable se convierte en una Lista o un Array costará una O (n) iteración sobre todos los elementos de la colección, lo que tendrá un impacto en el rendimiento cuando la colección sea grande.Aunque no tendemos a escribir código de esta manera llamando
.ToList()
entre llamadas LINQ, sería más frecuente cuando factorizamos el código en métodos reutilizables que devuelven enList/Array
lugar deIEnumerable
.Sin embargo, esto no significa que siempre debamos operar
IEnumerable
. Como lo mencionó Towlson , operaciones tales como.Count()
causarán iteración sobre la colección, mientras que List o Array tendrían esta información precalculada y, por lo tanto, la conversiónList/Array
sería más eficiente si planea llamar.Count()
varias veces. Esta es también la razón por la que hay una.Count
propiedad en una lista en lugar de un.Count()
método para contarla.fuente
Esta es una publicación antigua, pero aún pensé en responder. IEnumerable es un comportamiento mientras que Array es una estructura de datos (colección contigua de elementos con tamaño fijo, lo que facilita el acceso a elementos por índices). Cuando un Array implementa IEnumerable, se supone que también representa la propiedad inherente de IEnumerable (de facilitar la iteración sobre la colección).
fuente