Welches problem wird IStructuralEquatable und IStructuralComparable lösen?
Habe ich festgestellt, diese zwei Schnittstellen, und mehreren zugeordneten Klassen, Hinzugefügt wurden .NET 4. Sie scheinen ein wenig überflüssig für mich; ich habe gelesen, mehrere blogs über Sie, aber ich kann immer noch nicht herausfinden, welches problem Sie lösen, das war schwierig, vor .NET 4.
Was IStructuralEquatable
und IStructuralComparable
?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Alle Typen in .NET-Unterstützung die
Object.Equals()
- Methode, welche standardmäßig werden zwei Arten für Referenz-Gleichheit. Aber manchmal ist es auch wünschenswert, in der Lage sein zu vergleichen, zwei Arten für strukturelle Gleichheit.Das beste Beispiel dafür sind arrays, die mit .NET 4 implementieren Sie nun die
IStructuralEquatable
- Schnittstelle. Dies macht es möglich zu unterscheiden, ob Sie den Vergleich von zwei arrays auf Referenz-Gleichheit, oder für "strukturelle Gleichheit" - ob Sie die gleiche Anzahl von Elementen mit gleichen Werten in jeder position. Hier ist ein Beispiel:Andere Arten, die Umsetzung der strukturellen Gleichheit/Vergleichbarkeit enthalten Tupel und anonyme Typen, die beide eindeutig von Vorteil, die Fähigkeit zu führen-Vergleich, basierend auf deren Struktur und Inhalt.
Eine Frage, die Sie nicht Fragen, ist:
Die Antwort, die ich anbieten würde, ist, dass, im Allgemeinen, ist es wünschenswert, zu unterscheiden zwischen Referenz-Vergleiche und strukturelle Vergleiche. Es wird normalerweise erwartet, dass, wenn Sie implementieren
IEquatable<T>.Equals
Sie auch überschreibenObject.Equals
konsequent zu sein. In diesem Fall, wie würden Sie unterstützen sowohl die Referenz-und die strukturelle Gleichheit?IEqualityComparer
selbst, der dies tut? Was bedeutet dieIStructuralEquatable
interface hinzufügen?Equals
nimmt eineIEqualityComparer
- Array ist ein Beispiel, wenn ich mich Recht erinnere. Zweitens liefert eine Gleichstellung comparer ist schön, aber was ist, wenn Sie Ausdruck der Tatsache, dass eine bestimmte Methode erfordert zwei Objekte, die sich strukturell im Vergleich? Angegeben werden könnenIStructuralEquatable
/IStructuralComparable
in solchen Fällen tatsächlich nützlich ist. Es wäre auch unbequem sein, passieren eineTupleComparer
oderArrayComparer
überall Sie wollen anwenden diese Art von Vergleich. Die beiden Ansätze schließen sich nicht gegenseitig aus.IStructuralEquatable
- Schnittstelle. Aber das wäre einfach genug, um zu überprüfen, mit einigen test-code.X.EquivalentTo(Y)
Bedeutung, dass alle Mitglieder der Objekt bezeichnet, indemX
erwarten würde, Verhalten sich äquivalent zu denen das Objekt bezeichnet, indemY
, undX.ValueEquals(Y)
Bedeutung, die gleichzeitig das vertauschen von allen VerweiseX
undY
würde sich nicht auf das Verhalten der Mitglieder der beiden anderen, als eine äquivalenz-bezogenen hash-code. Beachten Sie, dass beide Definitionen, die ausgewertet werden können für Objekte von beliebiger - Typ. Beachten Sie, dass die BasisObject.EquivalentTo
...Object.ValueEquals
zurückkehren sollteTrue
[swapping alle, Verweise auf zwei InstanzenX
undY
TypSystem.Object
hätte keine sichtbaren Auswirkungen auf alle anderen Mitglieder als der äquivalenz-ZusammenhangGetHashCode
], sondern Personen, deren Staaten interagieren mit anderen Objekten überschreiben sollten, es zu testen, Referenz-Gleichheit.object.Equals
undobject.ReferenceEquals
.Equals
gemeint ist, außer Kraft gesetzt werden, für was auch immer Art von Vergleich am meisten Sinn macht, für eine gegebene Art, in der Erwägung, dassReferenceEquals
können nicht überschrieben werden, und vergleicht immer per Referenz.Ich hatte die gleiche Frage. Bei mir lief LBushkin Beispiel war ich überrascht zu sehen, dass ich mir eine andere Antwort! Obwohl, die Antwort hat 8 upvotes, ist es falsch. Nachdem eine Menge von 'Reflektor' Ing, hier ist mein nehmen auf Dinge.
Bestimmte Container (arrays, Tupel, anonyme Typen) support IStructuralComparable und IStructuralEquatable.
IStructuralComparable unterstützt deep, Standard-Sortierung.
IStructuralEquatable unterstützt deep, Standard-hashing.
{Beachten Sie, dass
EqualityComparer<T>
unterstützt sowohl flache (nur 1 container-Niveau), Standard-hashing.}Soweit ich sehe, dies ist nur ausgesetzt, durch die StructuralComparisons Klasse. Nur so kann ich herausfinden, zu machen, das nützlich ist, um eine
StructuralEqualityComparer<T>
helper-Klasse wie folgt:Nun können wir ein HashSet mit Elementen, die Container innerhalb von Containern innerhalb von Containern.
Können wir auch unsere eigenen container gut spielen mit diesen und anderen Behältern durch die Implementierung dieser Schnittstellen.
Nun können wir ein HashSet mit Elementen, die Container innerhalb des custom Container innerhalb von Containern.
Hier ist ein weiteres Beispiel, das veranschaulicht eine mögliche Verwendung der beiden interfaces:
Die Beschreibung der
IStructuralEquatable
Interface sagt (im Abschnitt "Hinweise"):Dies wird auch deutlich gemacht durch die Tatsache, dass diese Schnittstelle befindet sich in der
System.Collections
namespace.F# fingen an, Sie seit .net 4. ( .net 2 ist hier)
Diese Schnittstellen sind von entscheidender Bedeutung F#
C# in a nutshell Buch: