Por lo general, lo que elija dependerá de los métodos a los que necesite acceder. En general: IEnumerable<>
(MSDN: http://msdn.microsoft.com/en-us/library/system.collections.ienumerable.aspx ) para obtener una lista de objetos que solo necesitan iterarse, ICollection<>
(MSDN: http: // msdn.microsoft.com/en-us/library/92t2ye13.aspx ) para obtener una lista de objetos que deben iterarse y modificarse, List<>
para obtener una lista de objetos que deben iterarse, modificarse, ordenarse, etc. (Ver aquí para obtener una lista completa: http://msdn.microsoft.com/en-us/library/6sh2ey19.aspx ).
Desde un punto de vista más específico, la carga diferida entra en juego con la elección del tipo. Por defecto, las propiedades de navegación en Entity Framework vienen con seguimiento de cambios y son proxies. Para que el proxy dinámico se cree como una propiedad de navegación, se debe implementar el tipo virtual ICollection
.
Una propiedad de navegación que representa el extremo "muchos" de una relación debe devolver un tipo que implemente ICollection, donde T es el tipo del objeto en el otro extremo de la relación. - Requisitos para crear proxies de POCO MSDN
Más información sobre Definición y gestión de relaciones MSDN
List
debería ser mucho mejor, ¿sí?List
mucho. Aunque tiene la mayor sobrecarga, proporciona la mayor funcionalidad.private IEnumerable<int> _integers = new List<int> { 1, 2, 3 };
utiliza la misma memoria queprivate List<int> _integers = new List<int> { 1, 2, 3 };
List<T>
tiene unGetEnumerator()
método, independiente de su implementación deIEnumerable<T>
, que devuelve un tipo de estructura mutableList<T>.Enumerator
. En la mayoría de los contextos, ese tipo producirá un rendimiento ligeramente mejor que un objeto de montón independiente. Los compiladores que los enumeradores de tipo pato (como hacen C # y vb.net) pueden aprovechar esto al generarforeach
código. SiList<T>
se convierteIEnumrable<T>
antes deforeach
, elIEnumerable<T>.GetEnumerator()
método devolverá un objeto asignado en el montón, haciendo imposible la optimización.ICollection<T>
se utiliza porque laIEnumerable<T>
interfaz no proporciona forma de agregar elementos, eliminar elementos o modificar la colección.fuente
List<T>
implementosICollection<T>
.ICollection
no permite ninguna forma de agregar elementos, pero sigue siendo un complemento útilIEnumerable<T>
porque proporciona unCount
miembro que generalmente es mucho más rápido que enumerar todo. Tenga en cuenta que si se pasa unaIList<Cat>
oICollection<Cat>
al código que espera unaIEnumerable<Animal>
, elCount()
método de extensión será rápido si implementa lo no genéricoICollection
, pero no si solo implementa las interfaces genéricas, ya que una típicaICollection<Cat>
no se implementaráICollection<Animal>
.Respondiendo a su pregunta sobre
List<T>
:List<T>
es una clase especificar una interfaz permite una mayor flexibilidad de implementación. Una mejor pregunta es "¿por qué noIList<T>
?"Para responder a esa pregunta, considere lo que se
IList<T>
agrega aICollection<T>
: indexación de enteros, lo que significa que los elementos tienen un orden arbitrario y se pueden recuperar por referencia a ese orden. Esto probablemente no sea significativo en la mayoría de los casos, ya que los artículos probablemente deban ordenarse de manera diferente en diferentes contextos.fuente
Hay algunas diferencias básicas entre ICollection e IEnumerable
Programa simple:
fuente
Lo recuerdo así:
IEnumerable tiene un método GetEnumerator () que permite leer los valores de una colección pero no escribir en ellos. La mayor parte de la complejidad del uso del enumerador es tratada por nosotros para cada enunciado en C #. IEnumerable tiene una propiedad: Current, que devuelve el elemento actual.
ICollection implementa IEnumerable y agrega algunas propiedades adicionales, la mayoría de las cuales es Count. La versión genérica de ICollection implementa los métodos Add () y Remove ().
IList implementa tanto IEnumerable como ICollection, y agrega el acceso de indexación de enteros a los elementos (que generalmente no es necesario, ya que el pedido se realiza en la base de datos).
fuente
La idea básica de usar
ICollection
es proporcionar una interfaz para acceso de solo lectura a una cantidad finita de datos. De hecho, tiene una propiedad ICollection.Count .IEnumerable
es más adecuado para alguna cadena de datos donde se lee hasta algún punto lógico, alguna condición especificada de forma explícita por el consumidor o hasta el final de la enumeración.fuente
ICollection
es de solo lectura mientrasICollection<T>
que no lo es.Las propiedades de navegación generalmente se definen como virtuales para que puedan aprovechar ciertas funciones de Entity Framework, como la carga diferida.
Si una propiedad de navegación puede contener varias entidades (como en relaciones de varios a varios o de uno a varios), su tipo debe ser una lista en la que se pueden agregar, eliminar y actualizar entradas, como ICollection.
https://www.asp.net/mvc/overview/getting-started/getting-started-with-ef-using-mvc/creating-an-entity-framework-data-model-for-an-asp-net- aplicación mvc
fuente
Lo que he hecho en el pasado es declarar mis colecciones de clases internas usando
IList<Class>
,ICollection<Class>
oIEnumerable<Class>
(si es una lista estática) dependiendo de si tendré que hacer cualquier cantidad de lo siguiente en un método en mi repositorio: enumerar, ordenar / ordenar o modificar . Cuando solo necesito enumerar (y tal vez ordenar) sobre objetos, entonces creo un temporalList<Class>
para trabajar con la colección dentro de un método IEnumerable. Creo que esta práctica solo sería efectiva si la colección es relativamente pequeña, pero puede ser una buena práctica en general, idk. Corríjame si hay evidencia de por qué esto no sería una buena práctica.fuente
Tratemos de pensar fuera de la caja con / por lógica y comprenda claramente estas tres interfaces en su pregunta:
Cuando la clase de alguna instancia implementa la interfaz System.Collection.IEnumerable, entonces, en palabras simples, podemos decir que esta instancia es enumerable e iterable, lo que significa que esta instancia permite de alguna manera en un solo ciclo ir / obtener / pasar / recorrer / iterar sobre / a través de todos los elementos y elementos que contiene esta instancia.
Esto significa que también es posible enumerar todos los elementos y elementos que contiene esta instancia.
Cada clase que implementa la interfaz System.Collection.IEnumerable también implementa el método GetEnumerator que no toma argumentos y devuelve una instancia de System.Collections.IEnumerator.
Las instancias de la interfaz System.Collections.IEnumerator se comportan de manera muy similar a los iteradores de C ++.
Cuando la clase de alguna instancia implementa la interfaz System.Collection.ICollection, en palabras simples, podemos decir que esta instancia es una colección de cosas.
La versión genérica de esta interfaz, es decir, System.Collection.Generic.ICollection, es más informativa porque esta interfaz genérica establece explícitamente cuál es el tipo de elementos de la colección.
Todo esto es razonable, racional, lógico y tiene sentido que la interfaz System.Collections.ICollection herede de System.Collections.IEnumerable interfaz, porque teóricamente cada colección también es enumerable e iterable y esto es teóricamente posible revisar todos los elementos y elementos. en cada colección
La interfaz System.Collections.ICollection representa una colección dinámica finita que se puede cambiar, lo que significa que los elementos existentes se pueden eliminar de la colección y se pueden agregar nuevos elementos a la misma colección.
Esto explica por qué la interfaz System.Collections.ICollection tiene los métodos "Agregar" y "Eliminar".
Debido a que las instancias de la interfaz System.Collections.ICollection son colecciones finitas, la palabra "finito" implica que cada colección de esta interfaz siempre tiene un número finito de elementos y elementos.
La propiedad Cuenta de la interfaz System.Collections.ICollection supone devolver este número.
La interfaz System.Collections.IEnumerable no tiene estos métodos y propiedades que tiene la interfaz System.Collections.ICollection, porque no tiene ningún sentido que System.Collections.IEnumerable tenga estos métodos y propiedades que la interfaz System.Collections.ICollection tiene.
La lógica también dice que cada instancia que es enumerable e iterable no es necesariamente una colección y no necesariamente modificable.
Cuando digo cambiable, quiero decir que no piense de inmediato que puede agregar o eliminar algo de algo que es enumerable e iterable.
Si acabo de crear una secuencia finita de números primos, por ejemplo, esta secuencia finita de números primos es de hecho una instancia de System.Collections.IEnumerable interface, porque ahora puedo repasar todos los números primos en esta secuencia finita en un solo bucle y hacer lo que quiera hacer con cada uno de ellos, como imprimir cada uno de ellos en la ventana o pantalla de la consola, pero esta secuencia finita de números primos no es una instancia de la interfaz System.Collections.ICollection, porque esto no tiene sentido para agregue números compuestos a esta secuencia finita de números primos.
También desea en la próxima iteración obtener el siguiente número primo más cercano al número primo actual en la iteración actual, si es así, tampoco desea eliminar los números primos existentes de esta secuencia finita de números primos.
También es probable que desee usar, codificar y escribir "rendimiento de rendimiento" en el método GetEnumerator de la interfaz System.Collections.IEnumerable para producir los números primos y no asignar nada en el montón de memoria y luego asignar el recolector de basura (GC) a ambos desasignar y liberar esta memoria del montón, porque esto es obviamente un desperdicio de memoria del sistema operativo y disminuye el rendimiento.
La asignación de memoria dinámica y la desasignación en el montón se deben realizar al invocar los métodos y propiedades de la interfaz System.Collections.ICollection, pero no al invocar los métodos y propiedades de System.Collections.IEnumerable interfaz (aunque System.Collections.IEnumerable interface solo tiene 1 método y 0 propiedades).
Según lo que otros dijeron en esta página web de desbordamiento de pila, la interfaz System.Collections.IList simplemente representa una colección ordenable y esto explica por qué los métodos de la interfaz System.Collections.IList funcionan con índices en contraste con los de la interfaz System.Collections.ICollection.
En resumen, la interfaz System.Collections.ICollection no implica que una instancia de la misma sea ordenable, pero la interfaz System.Collections.IList sí lo implica.
El conjunto teóricamente ordenado es un caso especial de conjunto no ordenado.
Esto también tiene sentido y explica por qué la interfaz System.Collections.IList hereda la interfaz System.Collections.ICollection.
fuente