Question

J'ai un dictionnaire que je compare à un autre dictionnaire (variables typées comme IDictionary). Faire d1.Equals (d2) donne false. Écrire mon propre code ci-dessous donne la vérité. Les deux sont System.Collections.Generic.Dictionary. Est-ce que je manque quelque chose ou Dictionary je n'ai pas une Equals implémentation qui compare les clés / 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;
}
Était-ce utile?

La solution

Dictionary.Equals () utilise la valeur par défaut Equals from Object pour vérifier si les deux objets correspondent à la même référence, comme toutes les autres collections par défaut. Vous êtes libre de créer votre propre sous-classe avec une sémantique de valeur, même si cela inclut généralement des éléments immuables.

Autres conseils

La méthode Equals de la classe Dictionary utilise probablement simplement l'implémentation par défaut héritée de Object, c'est-à-dire qu'elle compare simplement la référence d'objet <=> transmise à sa propre référence. Voir ici: référence à Object.Equals

En supposant que deux dictionnaires, l'un étant SortedList<TKey, TValue> et l'autre Dictionary<TKey, TValue>, soient comparés aux fins de l'égalité, faut-il vraiment renvoyer la valeur true si les éléments sont identiques? Ce serait plutôt dommage, car ils ont des caractéristiques et des fonctionnalités différentes (SortedList<,> permet, par exemple, de récupérer des index via index).

De plus, l'égalité et le code de hachage sont logiquement liés. Le code de hachage doit être immuable, sinon tous les algorithmes basés sur le hachage ne fonctionneront pas. Vous ne pouvez pas garantir cela lorsque vous utilisez le contenu pour vérifier l'égalité. Par conséquent, l'implémentation par défaut (vérifier s'il s'agit bien de la même instance) est assez saine. Vous êtes libre de créer votre propre comparaison d’égalité de contenu.

D'autres ont indiqué qu'il utilisait l'implémentation Object.Equals. Vous pouvez utiliser les éléments suivants pour le remplacer:

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

Les références dans .NET peuvent être utilisées pour encapsuler l'identité d'un objet, les aspects modifiables de son état, les deux ou les deux non plus, en plus d'encapsuler les aspects immuables de l'état d'un objet. En général, en l'absence d'une raison particulière de supposer le contraire, .NET suppose que les références à des objets mutables sont utilisées dans le but d'encapsuler une identité. Cela suppose en outre que dans les cas où le code compare des références sans savoir ce qu'elles représentent, il est préférable de pécher par excès en signalant des choses inégales. En tant que tels, deux références à des objets mutables sont généralement considérées comme équivalentes si et seulement si elles identifient le même objet, et les types mutables sont donc découragés de remplacer Equals par autre chose. Le code qui utilise des références pour encapsuler un état mutable doit utiliser un moyen autre que Object.Equals() pour les comparer.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top