2011-09-27 12 views
49

Tengo una clase (SomeClass) que contiene una propiedad Name del tipo string. Y necesito almacenar una matriz de esa clase y encontrar sus elementos por sus nombres. Para este propósito, hay dos tipos de colecciones: KeyedCollection y Dictionary. Mi pregunta es: ¿qué diferencia hay entre ellos y en tal caso es mejor usar KeyedCollection y Dictionary? Gracias por cualquier ayuda en la explicación.Dictionary o KeyedCollection?

+2

Una ventaja (algo oscura?) De KeyedCollection, al menos si tiene control del proceso de serialización, es que solo tiene que serializar la parte de la Lista <> y enviarla "por el cable". No es necesario serializar ni enviar la parte Dictionary <> porque puede reconstruirse en el extremo receptor como parte de la deserialización de la parte List <>. – RenniePet

Respuesta

-11

No puede usar KeyedCollection porque es abstracto: http://msdn.microsoft.com/en-us/library/ms132438.aspx. Esto significa que no puedes crear un objeto de él.

+11

Fue diseñado específicamente para herencia, por lo que la comparación sobre la que OP está preguntando es entre usar un diccionario y algo que heredes de KeyedCollection. – mattmc3

14

Aquí es buena explicación sobre las diferencias entre diccionario y KeyedCollection: http://geekswithblogs.net/NewThingsILearned/archive/2010/01/07/using-keyedcollectionlttkey-titemgt.aspx

puntos principales son:

  • KeyedCollection es abstracto, por lo que no se pueden utilizar directamente.
  • KeyedCollection es útil para casos, cuando la clave está en la entidad misma, luego puede encapsular la recuperación de claves dentro de la implementación de la colección.
  • Existen implementaciones genéricas para KeyedCollection (aunque no en el framework), que le permiten pegar el delegado de recuperación de claves en el constructor de colecciones, para que no tenga que repetirlo cada vez que agrega un elemento.
5

De forma predeterminada, KeyedCollection crea un diccionario debajo de las carátulas.
Si la clave también tiene un significado como parte del valor y también define la singularidad, ese es el propósito de una colección con clave.

Si desea modificar el respaldo diccionario continuación, utilizar este ctor:

protected KeyedCollection(
IEqualityComparer<TKey> comparer, 
int dictionaryCreationThreshold) 
58

Ninguno de los comentarios anteriores aborda la diferencia más importante entre los dos: KeyedCollection mantiene sus elementos en el orden en que se encuentran agregado (el primer elemento agregado está en el índice 0 y el último añadido está en el último índice). El diccionario no lo hace (o al menos nunca se garantiza que lo haga).

Este beneficio adicional de KeyedCollection tiene un pequeño costo de rendimiento. Bajo las coberturas, usted paga el costo de mantener tanto un diccionario como una lista.

+0

Debe marcarse como respuesta. – Ted

+3

En particular, parece que el método Remove() es bastante ineficiente: busca secuencialmente en la lista para encontrar la entrada que se va a eliminar y luego desplaza las entradas restantes una posición hacia la izquierda. (Esto además de eliminar la entrada del Diccionario.) – RenniePet

+0

"KeyedCollection tiene un costo de rendimiento pequeño", pero presumiblemente esto depende de cómo lo use. También podría funcionar ligeramente mejor que un diccionario, por ejemplo [cuando se usa excesivamente con los bucles foreach] (http://stackoverflow.com/a/15904926/340045) ¿verdad? – Ben

4

Un KeyedCollection permite teclas y formas mutables para gestionar el cambio en la clave. El diccionario no permite cambios en la clave. En segundo lugar, si tiene una colección que necesita búsqueda, la lógica para extraer la clave de la entidad permanece en un solo lugar, mientras que el mantenimiento del diccionario necesitará colocar la lógica de extracción de clave en cada lugar donde se agregan/eliminan elementos del diccionario.

0

A KeyedCollection se debe utilizar cuando la clave está en el elemento en sí.

De forma predeterminada, KeyedCollection es un contenedor Collection<TItem> alrededor de un diccionario. Cuando utiliza colecciones pequeñas y/o prefiere recuperar elementos directamente, el KeyedCollectionprovides a constructor que toma un parámetro dictionaryCreationThreshold, que indica en qué recuento de colecciones pasar a Dictionary.
Otro aspecto en KeyedCollection es que puede optar por cambiar la propiedad de la clave (siempre que sus tipos coincidan). Esto puede ser bueno para elementos de doble clave, etc. En cuanto a rendimiento, no creo que envolver un diccionario tenga mucha sobrecarga, excepto si genera un grupo de instancias KeyedCollection, o si usa colecciones realmente grandes (hay algunas verificaciones internas null para determinar si hay un diccionario).
Una cosa que espero ver en KeyedCollection es un abstract ing it it, pero puede hacer que un tipo de concreto genérico sea igual de fácil.