web-dev-qa-db-fra.com

Dictionnaire c #: rendre la clé insensible à la casse grâce aux déclarations

J'ai un Dictionary<string, object> dictionnaire. C'était Dictionary<Guid, object> mais d'autres "identifiants" sont entrés en jeu et les clés sont désormais traitées comme des chaînes.

Le problème est que les clés Guid de mes données source viennent sous la forme VarChar, donc maintenant une clé de "923D81A0-7B71-438d-8160-A524EA7EFA5E" n'est pas la même chose que "923d81a0-7b71-438d-8160-a524ea7efa5e" (ce n'était pas un problème lors de l'utilisation de Guids).

Ce qui est vraiment sympa (et doux) avec le framework .NET, c'est que je peux faire ceci:

Dictionary<string, CustomClass> _recordSet = new Dictionary<string, CustomClass>(
    StringComparer.InvariantCultureIgnoreCase);

Et cela fonctionne très bien. Mais qu'en est-il d'un dictionnaire imbriqué? Comme le suivant:

Dictionary<int, Dictionary<string, CustomClass>> _customRecordSet 
    = new  Dictionary<int, Dictionary<string, CustomClass>>();

Comment spécifier le comparateur de chaînes sur un dictionnaire imbriqué comme celui-ci?

70
MoSlo

Lorsque vous ajoutez un élément au dictionnaire externe, vous créerez probablement une nouvelle instance du dictionnaire imbriqué, ajoutez-le à ce stade, en utilisant le constructeur surchargé qui prend un IEqualityComparer<TKey>.

_customRecordSet.Add(0, new Dictionary<string, CustomClass>(StringComparer.InvariantCultureIgnoreCase));


Mise à jour du 08/03/2017: De façon anecdotique, j'ai lu quelque part (je pense dans "Writing High-Performance .NET Code") que StringComparer.OrdinalIgnoreCase est plus efficace lorsque l'on veut simplement ignorer la casse des caractères. Ceci, cependant, est entièrement infondé par moi-même, donc YMMV.

77
Adam Houldsworth

Vous allez devoir initialiser les dictionnaires imbriqués pour les utiliser. Utilisez simplement le code que vous avez ci-dessus à ce stade.

Fondamentalement, vous devriez avoir du code comme celui-ci:

public void insert(int int_key, string guid, CustomClass obj)
{
    if (_customRecordSet.ContainsKey(int_key)
         _customRecordSet[int_key][guid] = obj;
    else
    {
         _customRecordSet[int_key] = new Dictionary<string, CustomClass> 
                                     (StringComparer.InvariantCultureIgnoreCase);
         _customRecordSet[int_key][guid] = obj;
    }
}
8
Patrick