2009-09-21 5 views
15

Je comprends qu'un dictionnaire n'est pas une collection ordonnée et que l'on ne devrait pas dépendre de l'ordre d'insertion et de récupération dans un dictionnaire.L'énumérateur d'un dictionnaire <TKey, TValue> renvoie-t-il les paires de valeurs clés dans l'ordre où elles ont été ajoutées?

Cependant, ce que je remarqué:

  • Ajouté 20 paires de valeurs clés à un dictionnaire
  • Récupéré les en faisant une foreach (KeyValuePair ...)

L'ordre de la récupération était la même que l'ordre dans lequel ils ont été ajoutés. Testé pour environ 16 paires de valeurs clés.

Est-ce intentionnel?

+0

question connexe: http://stackoverflow.com/questions/657263/does-hashset-preserve-insertion-order –

Répondre

26

C'est par coïncidence, bien que prévisible. Vous absolument ne devrait pas compter sur elle. Généralement arrivera pour des situations simples, mais si vous commencez à supprimer des éléments et à les remplacer par quelque chose avec le même code de hachage ou tout simplement entrer dans le même compartiment, cet élément prendra la position de l'original. que d'autres.

Il est relativement délicat à reproduire, mais je réussi à le faire il y a un moment for another question:

using System; 
using System.Collections.Generic; 

class Test 
{ 
    static void Main(string[] args) 
    { 
     var dict = new Dictionary<int, int>();   
     dict.Add(0, 0); 
     dict.Add(1, 1); 
     dict.Add(2, 2); 
     dict.Remove(0); 
     dict.Add(10, 10); 

     foreach (var entry in dict) 
     { 
      Console.WriteLine(entry.Key); 
     } 
    } 
} 

Les résultats montrent 10, 1, 2 au lieu de 1, 2, 10.

Remarque Même s'il semble que le comportement actuel produira toujours des éléments dans l'ordre d'insertion si vous n'effectuez aucune suppression, il n'y a aucune garantie que les implémentations futures feront la même chose ... même dans le cas restreint où vous vous connaissez ne supprimera rien, s'il vous plaît ne comptez pas sur cela.

+4

+1 - Cet exemple m'a aidé à reproduire le comportement dans mon scénario afin que je puisse le «voir» en action, ce qui m'aide à éviter les pièges potentiels. – AdaTheDev

21

De MSDN:

Aux fins de l'énumération, chaque élément dans le dictionnaire est traité comme une structure KeyValuePair<(Of <(TKey, TValue>)>) représentant une valeur et sa clé. L'ordre de retour des articles est indéfini.

[Je souligne]

0

Je ne pense pas, le dictionnaire ne GRANTEE pas l'ordre interne des éléments à l'intérieur. Si vous souhaitez également conserver la commande, utilisez une structure de données supplémentaire (tableau ou liste) avec le dictionnaire.

0

Je crois énumérant un Dictionary<K,V> va retourner les clés dans le même ordre où ils ont été insérés si toutes les clés hash à la même valeur. En effet, l'implémentation Dictionary<K,V> utilise le code de hachage de l'objet clé pour insérer des paires clé/valeur dans des compartiments, et les valeurs sont (généralement) stockées dans les compartiments dans l'ordre où elles sont insérées. Si vous rencontrez systématiquement ce comportement avec vos objets définis par l'utilisateur, vous n'avez peut-être pas (correctement) remplacé la méthode GetHashCode()?

2

C'est par conception que le Dictionary<TKey,TValue> n'est pas une structure ordonnée car il est destiné principalement à être utilisé pour l'accès par clé.

Si vous avez la nécessité de récupérer des éléments dans un ordre précis, vous devriez jeter un oeil à la Sorted Dictionary<TKey, TValue>, qui prend une Comparer<T> qui sera utilisé pour trier les clés du Sorted Dictionary<TKey, TValue>.

+0

Je pense que vous avez mal lu la question. Il demande si le fait qu'il * voit * les résultats dans l'ordre est voulu. –

+0

merci Jon, je voulais dire le fait que le dictionnaire n'est pas une structure ordonnée est par conception. Je vais clarifier ma réponse (ça peut être compliqué de répondre à un iPhone dans le train :)) –

+0

@Russ: Oui - j'ai compris ce que tu disais, mais ça ne répond pas à la question "est-ce que c'est par conception" :) –

3

Si vous voulez itérer un dictionnaire dans un ordre fixe, vous pouvez essayer OrderedDictionary

Questions connexes