C # Substitue Equals en utilisant & # 8220; en tant que & # 8221; et méthode spécialisée pour exactitude, flexibilité et performance

StackOverflow https://stackoverflow.com/questions/460846

Question

Je me suis demandé quelle était la meilleure façon de mettre en œuvre un Equals in C # correct, flexible et rapide, utilisable dans pratiquement toutes les classes et situations . J'ai pensé qu'un équivalent spécialisé (prenant un objet de la classe réelle comme paramètre) est nécessaire pour la performance. Pour éviter la duplication de code, les égaux généraux doivent appeler les égaux spécialisés. Les contrôles nuls ne doivent être effectués qu'une seule fois, même dans les classes héritées.

Je suis finalement venu avec ce design:


class MyClass
{
    public Int32 SomeValue1 = 1;
    public Int32 SomeValue2 = 25;

    // Ignoring GetHashCode for simplicity.

    public override bool Equals(object obj)
    {
        return Equals (obj as MyClass);
    }

    public bool Equals(MyClass obj)
    {
        if (obj == null) {
            return false;
        }

        if (!SomeValue1.Equals (obj.SomeValue1)) {
            return false;
        }

        if (!SomeValue2.Equals (obj.SomeValue2)) {
            return false;
        }

        return true;
    }
}

class MyDerivedClass : MyClass
{
    public Int32 YetAnotherValue = 2;

    public override bool Equals(object obj)
    {
        return Equals (obj as MyDerivedClass);
    }

    public bool Equals(MyDerivedClass obj)
    {
        if (!base.Equals (obj)) {
            return false;
        }

        if (!YetAnotherValue.Equals (obj.YetAnotherValue)) {
            return false;
        }

        return true;
    }
}

Idées importantes:

  • Utilisation de " comme " opérateur. De cette façon, nous n’avons pas à vérifier les valeurs nulles dans les égaux généraux. Les types de classe incorrects sont réduits à néant et seront triés dans les égaux spécialisés.
  • Vérification nulle à un moment donné, même pour les classes dérivées.
  • La vérification des attributs les uns après les autres fournit une structure claire.

Y at-il des défauts dans ce concept ou ai-je oublié des conditions?

Était-ce utile?

La solution

Votre méthode Equals n'est pas réflexive lorsque différents types sont impliqués:

MyDerivedClass mdc = new MyDerivedClass();
MyClass mc = new MyClass();
Object omdc = mdc;
Object omc = mc;

// mc.Equals(mdc) - true
// mdc.Equals(mc) - true by calling the right overload
// omc.Equals(omdc) - true
// omdc.Equals(omc) - false, the "as" in MyDerivedClass will result in null

La méthode normale consiste à utiliser:

if (GetType() != other.GetType())
{
    return false;
}

Consultez la documentation dans Object.Equals : & x; Equals (y) renvoie la même valeur que y.Equals (x). " Compter sur la surcharge pour obtenir des résultats différents peut aboutir à des problèmes horriblement qui seraient très subtils à déboguer.

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