Beide Schnittstellen scheinen Objekte auf Gleichheit zu vergleichen. Was sind also die Hauptunterschiede zwischen ihnen?
Beide Schnittstellen scheinen Objekte auf Gleichheit zu vergleichen. Was sind also die Hauptunterschiede zwischen ihnen?
Antworten:
IEquatable<T>
für die Gleichheit.
IComparable<T>
zur Bestellung.
Zusätzlich zu Greg Ds Antwort:
Sie könnten implementieren , IComparable
ohne die Umsetzung IEquatable
für eine Klasse , wo eine partielle Ordnung Sinn macht, und wo man sehr auf jeden Fall den Verbraucher zu schließen wollen , dass nur weil CompareTo()
Null zurückgibt, dies nicht bedeutet , dass die Objekte gleich sind (für etwas anderes als Sortierzwecke).
IComparable
ist hier völlig unangemessen. Was Sie haben, ist eine ganz bestimmte Bestellung, die nur in einer speziellen Situation gilt. In solchen Situationen ist die Implementierung eines Generals IComparable
falsch. Dafür sind wir IComparer
da. Zum Beispiel können Personen nicht sinnvoll bestellt werden. Sie können jedoch nach ihrem Gehalt, ihrer Schuhgröße, der Anzahl ihrer Sommersprossen oder ihrem Gewicht bestellt werden. Daher würden wir IComparer
für all diese Fälle unterschiedliche s implementieren .
Wie auf der MSDN-Seite für IEquatable angegeben :
Die IComparable-Schnittstelle definiert die
CompareTo
Methode, die die Sortierreihenfolge der Instanzen des Implementierungstyps bestimmt. Die IEquatable-Schnittstelle definiert dieEquals
Methode, die die Gleichheit der Instanzen des Implementierungstyps bestimmt.
Equals
vs. CompareTo
IComparable <T>
definiert eine typspezifische Vergleichsmethode, mit der Objekte sortiert oder sortiert werden können.
IEquatable <T>
definiert eine verallgemeinerte Methode, die zur Bestimmung der Gleichheit implementiert werden kann.
Angenommen, Sie haben eine Personenklasse
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
Person p1 = new Person() { Name = "Person 1", Age = 34 };
Person p2 = new Person() { Name = "Person 2", Age = 31 };
Person p3 = new Person() { Name = "Person 3", Age = 33 };
Person p4 = new Person() { Name = "Person 4", Age = 26 };
List<Person> people = new List<Person> { p1, p2, p3, p4 };
people.Sort();
.Dies wird jedoch eine Ausnahme auslösen.
Framework kann diese Objekte nicht sortieren. Sie müssen angeben, wie die Implementierungsschnittstelle sortiert IComparable
werden soll.
public class Person : IComparable
{
public string Name { get; set; }
public int Age { get; set; }
public int CompareTo(object obj)
{
Person otherPerson = obj as Person;
if (otherPerson == null)
{
throw new ArgumentNullException();
}
else
{
return Age.CompareTo(otherPerson.Age);
}
}
}
Dadurch wird das Array mit der Sort()
Methode ordnungsgemäß sortiert .
Equals()
Methode verwenden.var newPerson = new Person() { Name = "Person 1", Age = 34 };
var newPersonIsPerson1 = newPerson.Equals(p1);
Dies wird zurückgegeben,false
da die Equals
Methode nicht weiß, wie zwei Objekte verglichen werden sollen. Daher müssen Sie die IEquatable
Schnittstelle implementieren und dem Framework mitteilen, wie der Vergleich durchgeführt werden soll. Wenn Sie das vorherige Beispiel erweitern, sieht es so aus.
public class Person : IComparable, IEquatable<Person>
{
//Some code hidden
public bool Equals(Person other)
{
if (Age == other.Age && Name == other.Name)
{
return true;
}
else
{
return false;
}
}
}
IEquatable
ein Generikum verwendet <Person>
und IComparable
nicht?
IComparable
ordnungsgemäß implementiert wird. Können Sie mit einem aussagekräftigen Beispiel kommen , wennCompareTo(…) == 0
sie nicht der Gleichheit bedeuten? Ich kann es bestimmt nicht. Tatsächlich erfordert der Schnittstellenvertrag (gemäß MSDN) , dassCompareTo(…) == 0
Gleichheit impliziert wird. Um es ganz klar auszudrücken: Verwenden Sie in einem Fall wie Ihrem ein speziellesComparator
Objekt und implementieren Sie es nichtIComparable
.