Ich habe eine Klasse, die einige String-Member, einige Double-Member und einige Array-Objekte enthält.
Ich erstelle zwei Objekte dieser Klasse, gibt es eine einfache, effiziente Möglichkeit, diese Objekte zu vergleichen und ihre Gleichheit zu sagen? Irgendwelche Vorschläge?
Ich weiß, wie man eine Vergleichsfunktion schreibt, aber es wird zeitaufwendig sein.
Sie können dies nur dann tun, indem Sie bool Object.Equals(object other)
überschreiben, um wahr zurückzugeben, wenn Ihre Bedingungen für die Gleichheit erfüllt sind, und andernfalls false zurückgeben. Sie müssen auch int Object.GetHashCode()
überschreiben, um einen int zu berechnen, der aus all der Daten berechnet wurde, die Sie beim Überschreiben von Equals()
berücksichtigen.
Beachten Sie, dass der Vertrag für GetHashCode()
angibt, dass der Rückgabewert für zwei Objekte gleich sein muss, wenn Equals()
beim Vergleich True zurückgibt. Dies bedeutet, dass return 0;
eine gültige Implementierung von GetHashCode()
ist, aber es führt zu Ineffizienzen, wenn Objekte Ihrer Klasse als Dictionary-Schlüssel verwendet oder in einem HashSet<T>
gespeichert werden.
Die Art, wie ich die Gleichheit implementiere, ist wie folgt:
%Vor% Eine einfache Möglichkeit, GetHashCode()
zu implementieren, besteht darin, die Hash-Codes aller Daten, die Sie für die Gleichheit betrachten, in Equals()
zusammenzufassen. Wenn also zum Beispiel die Eigenschaften, die Sie für die Gleichheit vergleichen, string FirstName; string LastName; int Id;
sind, könnte Ihre Implementierung wie folgt aussehen:
Normalerweise überschreibe ich nicht die Gleichheitsoperatoren, da ich mich meistens nur mit der Gleichheit für Wörterbuchschlüssel oder -sammlungen befasse. Ich würde nur in Betracht ziehen, die Gleichheitsoperatoren zu überschreiben, wenn Sie wahrscheinlich mehr Vergleiche nach Wert als nach Verweis durchführen, da es syntaktisch weniger ausführlich ist. Sie müssen jedoch daran denken, alle Stellen zu ändern, an denen Sie ==
oder !=
für Ihr Objekt verwenden (einschließlich Ihrer Implementierung von Equals()
!), Um Object.ReferenceEquals()
zu verwenden, oder beide Operanden in object
zu konvertieren. Dieser fiese Gotcha (der eine unendliche Rekursion in Ihrem Gleichheitstest verursachen kann, wenn Sie nicht vorsichtig sind) ist einer der Hauptgründe, warum ich diese Operatoren selten überschreibe.
Die richtige Methode in .NET ist die Implementierung der IEquatable-Schnittstelle für Ihre Klasse:
%Vor%Wenn Sie es jedoch wirklich richtig machen möchten, das ist nicht alles, was Sie tun sollten . Sie sollten auch die Methoden Equals (object, object) und GetHashCode (object) überschreiben, so dass, egal wie Ihr aufrufender Code die Gleichheit vergleicht (vielleicht in einem Dictionary oder vielleicht in einer lose typisierten Sammlung), Ihr Code und nicht Referenz- Typ Gleichheit wird der entscheidende Faktor sein:
%Vor%Ich habe gerade den ganzen Tag damit verbracht, eine Erweiterungsmethode zu schreiben, die die Eigenschaften eines Objekts mit verschiedenen komplexen Bits der Logik durchkämmt, um mit verschiedenen Eigenschaftstypen umzugehen, und es dann tatsächlich um 16:55 Uhr so weit gebracht hat Wenn Sie die zwei Objekte serialisieren, müssen Sie einfach die beiden Strings vergleichen ... duh
Also hier ist eine einfache Serializer-Erweiterung-Methode, die sogar auf Wörterbücher funktioniert
%Vor%Jetzt kann Ihr Test so einfach sein wie
%Vor%Habe noch keine ausführlichen Tests gemacht, aber sieht vielversprechend und vor allem einfach aus. In jedem Fall noch eine nützliche Methode, um in Ihrem Dienstprogramm richtig eingerichtet zu haben?
Die beste Antwort ist, IEquatable für Ihre Klasse zu implementieren - es ist vielleicht nicht die Antwort, die Sie hören möchten, aber das ist der beste Weg, value equivalence in .NET zu implementieren.
Eine andere Option wäre, einen eindeutigen Hash aller Mitglieder Ihrer Klasse zu berechnen und dann Vergleiche mit diesen durchzuführen, aber das ist noch mehr Arbeit als das Schreiben einer Vergleichsfunktion;)
Da dies Objekte sind, ist es wahrscheinlich, dass Sie die Equals-Methode für Objekte überschreiben müssen. Andernfalls wird die Equals-Methode nur dann in Ordnung sein, wenn beide Objekte auf dasselbe Objekt verweisen.
Ich weiß, das ist nicht die Antwort, die Sie wollen. Aber da es in Ihrer Klasse nur wenige Eigenschaften gibt, können Sie die Methode leicht überschreiben.
Tags und Links c#