обидва інтерфейси, схоже, порівнюють об’єкти для рівності, то які основні відмінності між ними?
обидва інтерфейси, схоже, порівнюють об’єкти для рівності, то які основні відмінності між ними?
Відповіді:
IEquatable<T> за рівність.
IComparable<T> для замовлення.
На додаток до відповіді Грега Д.
Ви можете реалізовувати, IComparableне застосовуючи IEquatableдля класу, де часткове замовлення має сенс і де ви точно хочете, щоб споживач міг зробити висновок про те, що лише тому, що CompareTo()повертає нуль, це не означає, що об'єкти рівні (для будь-яких цілей, крім сортування).
IComparableтут цілком недоречно. У вас є дуже конкретне замовлення, яке застосовується лише в одній особливій ситуації. Для таких ситуацій реалізація генерала IComparableє неправильним. Для цього IComparerвони є. Наприклад, люди не можуть бути впорядкованими змістовно. Але їх можна замовити відповідно до зарплати, розміру взуття, кількості веснянок або ваги. Отже, ми б застосували різні IComparers для всіх цих випадків.
Як зазначено на сторінці 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.