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 IComparablesans implémenter IEquatablepour 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).
IComparableest 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 IComparableest 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 IComparers différents pour tous ces cas.
Comme indiqué sur la page MSDN pour IEquatable :
L'interface IComparable définit la
CompareTométhode, qui détermine l'ordre de tri des instances du type d'implémentation. L'interface IEquatable définit laEqualsmé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' IComparableinterface 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 Equalsméthode ne sait pas comment comparer deux objets. Par conséquent, vous devez implémenter l' IEquatableinterface 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;
}
}
}
IEquatableutilise un générique <Person>et IComparablenon?
IComparablecorrectement. Pouvez-vous proposer un exemple significatif oùCompareTo(…) == 0n'implique pas l' égalité? Je ne peux certainement pas. En fait, le contrat d'interface (selon MSDN) exige que celaCompareTo(…) == 0implique l'égalité. Pour le dire franchement, dans un cas comme le vôtre, utilisez unComparatorobjet spécial , ne l' implémentez pasIComparable.