Ich möchte, dass meine Food
Klasse testen kann, wann immer es einer anderen Instanz von entspricht Food
. Ich werde es später für eine Liste verwenden, und ich möchte seine List.Contains()
Methode verwenden. Soll ich implementieren IEquatable<Food>
oder einfach überschreiben Object.Equals()
? Von MSDN:
Diese Methode ermittelt die Gleichheit mithilfe des Standardgleichheitsvergleichs, der durch die Implementierung der IEquatable.Equals-Methode für T (den Wertetyp in der Liste) durch das Objekt definiert wird.
Meine nächste Frage lautet also: Welche Funktionen / Klassen des .NET Frameworks werden verwendet Object.Equals()
? Soll ich es überhaupt benutzen?
Antworten:
Der Hauptgrund ist die Leistung. Wenn Generika in .NET 2.0 eingeführt wurden sie in der Lage waren , ein paar ordentlichen Klassen hinzuzufügen wie
List<T>
,Dictionary<K,V>
,HashSet<T>
usw. machen diese Strukturen starke Nutzung vonGetHashCode
undEquals
. Für Werttypen erforderte dies jedoch Boxen.IEquatable<T>
Ermöglicht einer Struktur die Implementierung einer stark typisiertenEquals
Methode, sodass kein Boxen erforderlich ist. Somit viel bessere Leistung bei Verwendung von Werttypen mit generischen Sammlungen.Referenztypen profitieren nicht so sehr, aber mit der
IEquatable<T>
Implementierung können Sie eine Besetzung vermeiden,System.Object
die einen Unterschied machen kann, wenn sie häufig aufgerufen wird.Wie in Jared Parsons Blog erwähnt , müssen Sie die Objektüberschreibungen dennoch implementieren.
quelle
IEquatable<T>
Schnittstelle einen Entwickler lediglich daran, einpublic bool Equals(T other)
Mitglied in die Klasse oder Struktur aufzunehmen? Das Vorhandensein oder Fehlen der Schnittstelle macht zur Laufzeit keinen Unterschied. Die Überlastung vonEquals
scheint alles zu sein, was notwendig ist.Laut MSDN :
Es scheint also keinen wirklichen funktionalen Unterschied zwischen den beiden zu geben, außer dass beide aufgerufen werden könnten, abhängig davon, wie die Klasse verwendet wird. Unter Leistungsgesichtspunkten ist es besser, die generische Version zu verwenden, da damit keine Box- / Unboxing-Strafe verbunden ist.
Aus logischer Sicht ist es auch besser, die Schnittstelle zu implementieren. Das Überschreiben des Objekts sagt niemandem wirklich, dass Ihre Klasse tatsächlich gleichwertig ist. Die Überschreibung kann nur eine Do-Nothing-Klasse oder eine flache Implementierung sein. Über die Schnittstelle wird explizit gesagt: "Hey, dieses Ding ist für die Gleichheitsprüfung gültig!" Es ist einfach besseres Design.
quelle
Erweitern Sie das, was Josh gesagt hat, um ein praktisches Beispiel. +1 an Josh - Ich wollte das gleiche in meiner Antwort schreiben.
Auf diese Weise habe ich eine wiederverwendbare Equals () -Methode, die für alle meine abgeleiteten Klassen sofort funktioniert.
quelle
Wenn wir anrufen
object.Equals
, zwingt es zu teurem Boxen auf Werttypen. Dies ist in leistungsabhängigen Szenarien unerwünscht. Die Lösung ist zu verwendenIEquatable<T>
.Die Idee dahinter
IEquatable<T>
ist, dass es das gleiche Ergebnis liefert,object.Equals
aber schneller. Die Einschränkungwhere T : IEquatable<T>
muss mit generischen Typen wie unten verwendet werden.Andernfalls bindet es an
slower object.Equals()
.quelle