2010-04-27 22 views
24

Por extraño que parezca, MSDN no tiene información sobre el orden en que se conservan las propiedades de las estructuras de datos. Así que he estado haciendo la suposición de que:C# preservar las estructuras de datos

  • tabla hash y hashset no preservan el orden de inserción (también conocido como el "control" en la que hay un claro indicativo)
  • Diccionario y hacer la lista de preservar el orden de inserción.

de esta I extrapolar que si tengo una Dictionary<double,double> foo que define una curva, foo.Keys.ToList() y foo.Values.ToList() me dará una lista ordenada del alcance y el dominio de la curva sin jugar con eso?

Respuesta

32

NO debe esperar que las claves o valores en un Dictionary<TKey,TValue> normal se mantengan en cualquier orden. En un SortedDictionary<TKey,TValue> las claves y los valores se mantienen en orden por el valor de la clave - , esto no es lo mismo que el pedido de inserción.

El único diccionario incorporado en el marco .NET que conserva el orden de inserción es System.Collections.Specialized.OrderedDictionary. Desafortunadamente, esta clase no es genérica, sin embargo, no es terriblemente difícil escribir un contenedor genérico a su alrededor. Tenga en cuenta que, al tratar con tipos de valores (como int o double), dará lugar al encajonamiento de las claves/valores (los diccionarios genéricos no imponen el boxeo en los tipos de valores).

+1

esto es lo que inicialmente asumí, pero luego, un poco más de Google parecía haber sugerido que el Diccionario SÍ mantiene el orden de inserción. OrderedDictionary es. ¡Gracias! –

1

Como @Anton señaló que el Dictionary<TKey,TValue> es una colección desordenada. El retorno adecuado de sus valores es una coincidencia y eventualmente fallará. Si necesita tener una tabla hash ordenada, debe usar SortedDictionary<TKey,TValue>

+10

'SortedDictionary ' no conserva el orden de inserción, mantiene los elementos en función de un orden natural de las teclas. Hay una clase 'OrderedDictionary' no genérica en el espacio de nombres' System.Collections.Specialized' que * does * preserva el orden de inserción a costa de un almacenamiento adicional. (Básicamente se implementa como una tabla hash y una lista). – LBushkin

-8

¡Por supuesto, confíe en Dictionary<TKey, TValue> para conservar el orden!

Mientras que Dictionary<TKey, TValue> indica claramente que el orden de enumeración no está definido, probamos que de hecho conserva el orden de inserción (al menos mientras no elimine elementos de él). Si alguien puede proporcionar una prueba que lo desmiente, estaríamos muy interesados ​​ya que nuestro código de producción se basa en él.

Puede tomar el mismo enfoque y ahorrarse un poco de esfuerzo y su cliente algo de dinero.

Claro, Microsoft podría cambiar la implementación del diccionario en una futura versión de .NET, pero si eso sucede, su prueba automatizada lo detectará, y puede reemplazar el diccionario con otro contenedor en ese momento, ¿no?

+13

¿Confía en esta característica _en el código de producción _ ??? ¿Estas loco? El diccionario no preserva específicamente el orden de inserción, el hecho de que lo haga en su caso es en gran medida un caso marginal y un efecto secundario de cómo lo está usando.Puedes ver esto al echar un vistazo al método 'Insertar 'en el reflector: usa el código hash clave para determinar dónde colocar la entrada en las matrices de respaldo, y luego itera a través de las matrices en el' Enumerador' – thecoop

+2

@thecoop : Estoy de acuerdo en que confiar en el orden temporal es peligroso, pero hay más cosas que hacen que el 'Diccionario' se comporte de esta manera por algo más que un caso marginal. En realidad, mantiene dos matrices. Uno para los elementos reales almacenados (entradas) y uno para el índice en el primero (cubos). Los nuevos elementos siempre se agregan a la siguiente ranura disponible en la matriz de entrada, independientemente de lo que ocurra con los códigos hash y la matriz de cubetas. Incluso si elimina un elemento, el orden de esa matriz de entrada sigue siendo determinista (aunque ya no sea temporal). Nuevamente, nunca confiaría en este detalle. –

+2

Créanme, estábamos tan sorprendidos como ustedes, pero por más que lo intentamos, no pudimos escribir una prueba que rompiera nuestro código de producción (en ese punto, de todos modos, jeje). También escribimos una prueba para insertar un millón de elementos en orden aleatorio en un diccionario, iterarlo y afirmar que los elementos salen en el mismo orden en que se insertaron. Y de nuevo, las autoexploraciones nos dirán si por alguna razón no podemos confiar en ello en el futuro. –