Frage

ich habe ein klasse Person, implementiert es die Equals()-Methode von IEquatable<Person> (überschreibt auch Object.Equals Methode, ignorieren wir vorerst die GetHashcode()-Methode)

class Person : IEquatable<Person>
{
    public string Name { get; set; }

    public bool Equals(Person other)
    {
        return this.Name == other.Name;
    }
    public override bool Equals(object obj)
    {
        var person = obj as Person;
        return person != null && person.Name == Name;
    }
}

In Ordnung, lass uns anfangen:

Person p1 = new Person() { Name = "a" };
Person p2 = new Person() { Name = "a" };

List<Person> lst1 = new List<Person>() { p1 };
List<Person> lst2 = new List<Person>() { p2 };

Reden wir über diese Zeile:

 bool b = lst1.SequenceEqual(lst2, EqualityComparer<Person>.Default);

Ich habe ein Problem damit, diesen Teil zu verstehen:

EqualityComparer<Person>.Default

Das habe ich gehört EqualityComparer<Person>.Default prüft, ob die Klasse implementiert wird IEquatable - Es wird dauern Equals(Person other) Methode und nicht die Equals(object obj). Es hat den Vorteil, dass Boxen vermieden wird

enter image description here Aber

Die Equals(Person other) werde rennen mit oder ohne EqualityComparer<Person>.Default(weil es IEquatable implementiert)

Über welches Boxen reden wir also?Gibt es nicht!

Das einzige Mal, dass Equals(object obj) wird ausgeführt, wenn:

bool b = lst1.SequenceEqual(lst2,EqualityComparer<Object>.Default);

Aber Ich bin Programmierer!Ich werde niemals eine senden object wenn es tatsächlich ein Person!

Was vermisse ich?Es fällt mir schwer, den Nutzen hiervon zu verstehen EqualityComparer<Object>.Default.Kann mir bitte jemand ein Beispiel geben, um zu beweisen, dass ich falsch liege?

War es hilfreich?

Lösung

Wenn du vorbeikommst null als zweiten Parameter oder wenn Sie überhaupt kein zweites Argument übergeben (was im Grunde dasselbe ist), wird die Implementierung von SequenceEquals aufgerufen EqualityComparer<T>.Default selbst (dekompilieren Enumerable um das zu sehen).Das erklärt, warum Sie keinen Unterschied sehen, ob Sie etwas bereitstellen EqualityComparer<T>.Default oder nicht.

Letztendlich macht der zweite Parameter also nur dann Sinn, wenn Sie einen Gleichheitsvergleicher verwenden möchten außer EqualityComparer<T>.Default.

Andere Tipps

Dass du hineingehen kannst IEqualityComparer<object>.Default ist eine Wirkung von generische Kontravarianz, hinzugefügt in .NET 4.

Im Wesentlichen ein IEqualityComparer<BaseType> kann immer dann verwendet werden IEqualityComparer<DerivedType> ist erforderlich, wo DerivedType : BaseType.Seit Person kommt von Object, das bedeutet, dass ein IEqualityComparer<Object> überall einsetzbar IEqualityComparer<Person> ist erforderlich.

Die Antwort ist hier: http://msdn.microsoft.com/en-us/library/ms131187(v=vs.110).aspx

Für einen Werttyp sollten Sie für eine bessere Leistung immer IEquatable implementieren und Object.Equals(Object) überschreiben.Object.Equals fasst Werttypen zusammen und verwendet Reflektion, um zwei Werte auf Gleichheit zu vergleichen.Sowohl Ihre Implementierung von Equals als auch Ihre Überschreibung von Object.Equals sollten konsistente Ergebnisse liefern.

Wenn Sie Equals und GetHashCode nicht überschreiben, übernimmt EqualityComparer.Default dies tatsächlich für Sie.

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