oba interfejsy wydają się porównywać obiekty pod kątem równości, więc jakie są główne różnice między nimi?
c#
interface
icomparable
iequatable
SoftwareGeek
źródło
źródło
IComparable
poprawnie implementujący . Można wymyślić sensowny przykład gdzieCompareTo(…) == 0
ma nie implikuje równość? Ja na pewno nie mogę. W rzeczywistości kontrakt interfejsu (zgodnie z MSDN) wymaga, abyCompareTo(…) == 0
implikować równość. Mówiąc wprost, w takim przypadku jak twój użyj specjalnegoComparator
przedmiotu, nie implementujIComparable
.IComparable
jest 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łaIComparable
jest niewłaściwa. Po toIComparer
tam 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 weIComparer
wszystkich tych przypadkach zaimplementowalibyśmy różne .Jak podano na stronie MSDN dla IEquatable :
Equals
vs.CompareTo
źródło
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 };
Aby posortować te obiekty, możesz użyć
people.Sort();
.Ale to spowoduje wyjątek.
Framework nie wie, jak sortować te obiekty. Musisz powiedzieć, jak sortować
IComparable
interfejs 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.Obok porównania dwóch obiektów możesz skorzystać z
Equals()
metody method.var newPerson = new Person() { Name = "Person 1", Age = 34 }; var newPersonIsPerson1 = newPerson.Equals(p1);
To zwróci,
false
ponieważEquals
metoda nie wie, jak porównać dwa obiekty. Dlatego musisz zaimplementowaćIEquatable
interfejs 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; } } }
źródło
IEquatable
używa generycznego,<Person>
aIComparable
nie?