обидва інтерфейси, схоже, порівнюють об’єкти для рівності, то які основні відмінності між ними?
обидва інтерфейси, схоже, порівнюють об’єкти для рівності, то які основні відмінності між ними?
Відповіді:
IEquatable<T>
за рівність.
IComparable<T>
для замовлення.
На додаток до відповіді Грега Д.
Ви можете реалізовувати, IComparable
не застосовуючи IEquatable
для класу, де часткове замовлення має сенс і де ви точно хочете, щоб споживач міг зробити висновок про те, що лише тому, що CompareTo()
повертає нуль, це не означає, що об'єкти рівні (для будь-яких цілей, крім сортування).
IComparable
тут цілком недоречно. У вас є дуже конкретне замовлення, яке застосовується лише в одній особливій ситуації. Для таких ситуацій реалізація генерала IComparable
є неправильним. Для цього IComparer
вони є. Наприклад, люди не можуть бути впорядкованими змістовно. Але їх можна замовити відповідно до зарплати, розміру взуття, кількості веснянок або ваги. Отже, ми б застосували різні IComparer
s для всіх цих випадків.
Як зазначено на сторінці MSDN для IEquatable :
Інтерфейс IComparable визначає
CompareTo
метод, який визначає порядок сортування екземплярів типу реалізації. Інтерфейс IEquatable визначаєEquals
метод, який визначає рівність екземплярів типу реалізації.
Equals
vs. CompareTo
IComparable <T>
визначає специфічний для конкретного типу метод порівняння, який можна використовувати для впорядкування або сортування об’єктів.
IEquatable <T>
визначає узагальнений метод, який може бути використаний для реалізації для визначення рівності.
Скажімо, у вас є клас Особи
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();
.Але це кине виняток.
Framework не знає, як сортувати ці об’єкти. Вам потрібно розповісти, як сортувати IComparable
інтерфейс реалізації .
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);
}
}
}
Це буде сортувати масив належним чином за Sort()
методом.
Equals()
метод.var newPerson = new Person() { Name = "Person 1", Age = 34 };
var newPersonIsPerson1 = newPerson.Equals(p1);
Це повернеться,false
оскільки Equals
метод не знає, як порівняти два об’єкти. Тому вам потрібно реалізувати IEquatable
інтерфейс і сказати фреймворку, як зробити порівняння. Продовжуючи попередній приклад, це виглядатиме так.
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
використовується загальний, <Person>
а IComparable
ні?
IComparable
належним чином. Можете чи ви придумати змістовний прикладом , деCompareTo(…) == 0
це НЕ має на увазі рівність? Я точно не можу. Насправді, інтерфейсний контракт (згідно з MSDN) вимагає, щоCompareTo(…) == 0
передбачає рівність. Якщо прямо сказати, у такому випадку, як ваш, використовуйте спеціальнийComparator
об’єкт, не реалізовуйтеIComparable
.