C # Zwingende Equals „als“ und spezialisierte Verfahren für die Richtigkeit, Flexibilität und Leistung mit

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

Frage

fragte ich mich über die beste Art und Weise ein richtig, flexibel und schnell Equals in C # zu implementieren, das praktisch für jede Klasse und die Situation verwendet werden kann . Ich stellte dar, dass eine spezialisierte Equals (ein Objekt der tatsächlichen Klasse als Parameter genommen wird) ist für die Leistung benötigt wird. Um Code Doppelarbeit zu vermeiden, müssen die allgemeinen Equals sollten die spezialisierten Equals nennen. Null Kontrollen sollten nur einmal, auch in geerbten Klassen durchgeführt werden.

Ich kam schließlich mit diesem Entwurf:


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;
    }
}

Wichtige Ideen:

  • Die Verwendung des "als" Operator. Auf diese Weise müssen wir für NULL-Werte in dem allgemeinen Equals nicht überprüfen. Falsche Klasse Typen reduziert, um zu null und werden in dem spezialisierten Equals aussortiert werden.
  • Null-Check an genau einen Punkt, auch für abgeleitete Klassen.
  • Überprüfen Sie die Attribute einer nach dem anderen eine klare Struktur bereitstellt.

Gibt es Mängel in diesen Konzepten oder versäumen ich irgendwelche Bedingungen?

War es hilfreich?

Lösung

Ihre Equals-Methode ist nicht reflexiv, wenn verschiedene Arten beteiligt sind:

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

Der normale Weg rund um diesen zu bedienen ist:

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

Lesen Sie die Dokumentation in Object.Equals : „x.Equals (y) gibt den gleichen Wert wie y.Equals (x).“ Unter Berufung auf eine Überlastung zu unterschiedlichen Ergebnissen führen könnte am Ende mit schrecklich Fragen, die sehr subtil zu debuggen sein würde.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top