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 , IComparableohne die Umsetzung IEquatablefü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).
IComparableist 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 IComparablefalsch. Dafür sind wir IComparerda. 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 IComparerfür all diese Fälle unterschiedliche s implementieren .
Wie auf der MSDN-Seite für IEquatable angegeben :
Die IComparable-Schnittstelle definiert die
CompareToMethode, die die Sortierreihenfolge der Instanzen des Implementierungstyps bestimmt. Die IEquatable-Schnittstelle definiert dieEqualsMethode, 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 IComparablewerden 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 EqualsMethode nicht weiß, wie zwei Objekte verglichen werden sollen. Daher müssen Sie die IEquatableSchnittstelle 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;
}
}
}
IEquatableein Generikum verwendet <Person>und IComparablenicht?
IComparableordnungsgemäß implementiert wird. Können Sie mit einem aussagekräftigen Beispiel kommen , wennCompareTo(…) == 0sie nicht der Gleichheit bedeuten? Ich kann es bestimmt nicht. Tatsächlich erfordert der Schnittstellenvertrag (gemäß MSDN) , dassCompareTo(…) == 0Gleichheit impliziert wird. Um es ganz klar auszudrücken: Verwenden Sie in einem Fall wie Ihrem ein speziellesComparatorObjekt und implementieren Sie es nichtIComparable.