oba interfejsy wydają się porównywać obiekty pod kątem równości, więc jakie są główne różnice między nimi?
oba interfejsy wydają się porównywać obiekty pod kątem równości, więc jakie są główne różnice między nimi?
Odpowiedzi:
IEquatable<T> dla równości.
IComparable<T> do zamówienia.
Oprócz odpowiedzi Grega D.
Możesz zaimplementować IComparablebez implementacji IEquatabledla klasy, w której częściowe porządkowanie ma sens i gdzie zdecydowanie chcesz, aby konsument wywnioskował, że tylko dlatego, że CompareTo()zwraca zero, nie oznacza to, że obiekty są równe (w celach innych niż sortowanie).
IComparablejest tutaj całkowicie niewłaściwy. To, co masz, to bardzo szczególna kolejność, która ma zastosowanie tylko w jednej specjalnej sytuacji. W takich sytuacjach implementacja generała IComparablejest niewłaściwa. Po to IComparertam są. Na przykład nie można porządkować ludzi. Ale można je sortować według wynagrodzenia, rozmiaru buta, liczby piegów lub wagi. Dlatego we IComparerwszystkich tych przypadkach zaimplementowalibyśmy różne .
Jak podano na stronie MSDN dla IEquatable :
Interfejs IComparable definiuje
CompareTometodę, która określa kolejność sortowania wystąpień typu implementującego. Interfejs IEquatable definiujeEqualsmetodę, która określa równość wystąpień typu implementującego.
Equals vs. CompareTo
IComparable <T> definiuje metodę porównania specyficzną dla typu, której można użyć do porządkowania lub sortowania obiektów.
IEquatable <T> definiuje uogólnioną metodę, której można użyć do określenia równości.
Powiedzmy, że masz klasę Person
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();.Ale to spowoduje wyjątek.
Framework nie wie, jak sortować te obiekty. Musisz powiedzieć, jak sortować IComparableinterfejs implementujący .
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);
}
}
}
Spowoduje to prawidłowe posortowanie tablicy przy użyciu Sort()metody method.
Equals()metody method.var newPerson = new Person() { Name = "Person 1", Age = 34 };
var newPersonIsPerson1 = newPerson.Equals(p1);
To zwróci,false ponieważ Equalsmetoda nie wie, jak porównać dwa obiekty. Dlatego musisz zaimplementować IEquatableinterfejs i powiedzieć frameworkowi, jak wykonać porównanie. Rozszerzając poprzedni przykład, będzie wyglądać tak.
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;
}
}
}
IEquatableużywa generycznego, <Person>a IComparablenie?
IComparablepoprawnie implementujący . Można wymyślić sensowny przykład gdzieCompareTo(…) == 0ma nie implikuje równość? Ja na pewno nie mogę. W rzeczywistości kontrakt interfejsu (zgodnie z MSDN) wymaga, abyCompareTo(…) == 0implikować równość. Mówiąc wprost, w takim przypadku jak twój użyj specjalnegoComparatorprzedmiotu, nie implementujIComparable.