9
votes

Le dictionnaire.equals () a-t-il une implémentation?

J'ai un dictionnaire que je comparais à un autre dictionnaire (variables dactylographiés en tant que cahicotement). Faire d1.equals (D2) donne de faux. Écrire mon propre code ci-dessous donne vrai. Les deux sont system.collections.generic.dictionary code>. Est-ce que je manque quelque chose ou fait dictionnaire code> ne pas avoir un est égal à la mise en œuvre code> qui compare les touches / valeurs?

private static bool DictEquals<K, V>(IDictionary<K, V> d1, IDictionary<K, V> d2)
{
    if (d1.Count != d2.Count)
        return false;

    foreach (KeyValuePair<K, V> pair in d1)
    {
        if (!d2.ContainsKey(pair.Key))
            return false;

        if (!Equals(d2[pair.Key], pair.Value))
            return false;
    }

    return true;
}


0 commentaires

5 Réponses :


5
votes

Probablement le Equals Méthode du dictionnaire La classe a recours simplement à la mise en œuvre par défaut héritée de objet , c'est-à-dire qu'il s'agit simplement de la < Code> Dictionnaire Référence d'objet passée avec sa propre référence. Voir ici: Référence Objet.equales


0 commentaires

12
votes

Dictionary.equals () utilise les égaux par défaut de l'objet, vérifiant si les deux objets sont la même référence, tout comme toutes les autres collections par défaut. Vous êtes libre de créer votre propre sous-classe avec une sémantique de valeur, cependant, cela inclut généralement des choses qui sont immuables.


1 commentaires

+1, comme indiqué dans la documentation de la classe de dictionnaire. msdn.microsoft.com/en-us/library/3eayzh46.aspx.



1
votes

D'autres personnes ont mentionné qu'il utilise l'objet d'objet.equals, vous pouvez utiliser ce qui suit pour le remplacer:

public class EqualsDictionary<T, T> : Dictionary<T, T>
{
    public override bool Equals(object obj)
    {
        //Place your comparison implementation here
    }
}


2 commentaires

remplacer , comme le mot clé dit. La surcharge est quelque chose de différent.


@Joren: Yup, toujours trop tôt pour moi.



2
votes

En supposant que deux dictionnaires, l'un étant un sortidlist et un Dictionnaire est comparé à l'égalité, devrait-il vraiment revenir vrai si les articles sont les mêmes? Ce serait plutôt mauvais, car ils ont des caractéristiques et des fonctionnalités différentes (le trié <,> par exemple permet une récupération via index).

Aussi, l'égalité et le code de hachage sont logiquement liés ensemble. Le code de hachage doit être immuable, sinon tous les algorithmes de hachage ne fonctionneront pas. Vous ne pouvez pas garantir cela lorsque vous utilisez le contenu pour vérifier l'égalité. Par conséquent, la mise en œuvre par défaut (vérification s'ils sont le même exemple) est assez sain d'esprit. Vous êtes libre de créer votre propre comparaison sur l'égalité de contenu.


3 commentaires

Point équitable, mon code ci-dessus doit faire la vérification de la classe d'identité + classe habituelle avant de comparer le contenu.


Droit. Toutefois, cela ne serait toujours pas un remplacement approprié pour les égaux () en raison de la question de code HashCode: si deux objets sont égaux, leur code HASH doit être égal et le code de hachage doit être immuable. En conséquence, les égaux () peuvent ne pas retourner vrai simplement parce que deux collections sont du même type avec le même contenu, car ils auront toujours une différence (immuable, désolée de le stresser).


@LUCERO: C'est dommage que .NET définit uniquement un ensemble de méthodes de relation d'équivalence virtuelle, puisque la plupart des types de classe "immuables" contiennent des références à des objets qui seraient mutables sauf que les références ne seront jamais exposées à rien Mutater-les et il serait utile s'il y avait des méthodes standard que ces classes d'emballage immuables pouvaient utiliser pour hacher ou vérifier l'égalité sur leur contenu.



0
votes

Les références dans .NET peuvent être utilisées pour encapsuler l'identité d'un objet, des aspects mutables de son état, à la fois ou non, en plus d'encapsuler des aspects immuables de l'état d'un objet. En général, absent une raison particulière d'assumer autrement, .NET suppose que les références à des objets mutables sont utilisées dans le but d'encapsuler l'identité. Il suppose en outre que dans les cas où le code comparait des références sans savoir ce qu'elles représentent, il est préférable de vous tromper du côté de la déclaration des choses inégales. En tant que telles, deux références à des objets mutables sont généralement considérées comme équivalentes si et seulement s'ils identifient le même objet, et des types mutables sont donc déconseillés à partir du remplacement égale pour indiquer autre chose. Au lieu de cela, le code qui utilise des références à l'encapsulation de l'état mutable doit utiliser des moyens autres que objet.equaux () pour les comparer.


0 commentaires