les deux interfaces semblent comparer les objets pour l'égalité, alors quelles sont les principales différences entre eux?
les deux interfaces semblent comparer les objets pour l'égalité, alors quelles sont les principales différences entre eux?
Réponses:
IEquatable<T>
pour l'égalité.
IComparable<T>
pour la commande.
En plus de la réponse de Greg D:
Vous pouvez implémenter IComparable
sans implémenter IEquatable
pour une classe où un ordre partiel a du sens, et où vous voulez très certainement que le consommateur en déduit que simplement parce que CompareTo()
renvoie zéro, cela n'implique pas que les objets sont égaux (pour autre chose que le tri).
IComparable
est totalement inappropriée ici. Ce que vous avez, c'est un ordre très particulier qui ne s'applique que dans une situation particulière. Dans de telles situations, la mise en œuvre d'un général IComparable
est une erreur. C'est pour ça que IComparer
ça sert . Par exemple, les gens ne peuvent pas être ordonnés de manière significative. Mais ils peuvent être commandés en fonction de leur salaire, de leur pointure, du nombre de leurs taches de rousseur ou de leur poids. Par conséquent, nous implémenterions des IComparer
s différents pour tous ces cas.
Comme indiqué sur la page MSDN pour IEquatable :
L'interface IComparable définit la
CompareTo
méthode, qui détermine l'ordre de tri des instances du type d'implémentation. L'interface IEquatable définit laEquals
méthode, qui détermine l'égalité des instances du type d'implémentation.
Equals
contre. CompareTo
IComparable <T>
définit une méthode de comparaison spécifique au type qui peut être utilisée pour ordonner ou trier des objets.
IEquatable <T>
définit une méthode généralisée qui peut être utilisée pour implémenter pour déterminer l'égalité.
Disons que vous avez la classe 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();
.Mais cela lèvera une exception.
Framework ne sait pas comment trier ces objets. Vous devez dire comment trier l' IComparable
interface d' implémentation .
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);
}
}
}
Cela triera correctement le tableau avec la Sort()
méthode.
Equals()
méthode.var newPerson = new Person() { Name = "Person 1", Age = 34 };
var newPersonIsPerson1 = newPerson.Equals(p1);
Cela reviendrafalse
car la Equals
méthode ne sait pas comment comparer deux objets. Par conséquent, vous devez implémenter l' IEquatable
interface et indiquer au framework comment effectuer la comparaison. En prolongeant l'exemple précédent, cela ressemblera à ceci.
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
utilise un générique <Person>
et IComparable
non?
IComparable
correctement. Pouvez-vous proposer un exemple significatif oùCompareTo(…) == 0
n'implique pas l' égalité? Je ne peux certainement pas. En fait, le contrat d'interface (selon MSDN) exige que celaCompareTo(…) == 0
implique l'égalité. Pour le dire franchement, dans un cas comme le vôtre, utilisez unComparator
objet spécial , ne l' implémentez pasIComparable
.