ambas as interfaces parecem comparar objetos por igualdade, então quais são as principais diferenças entre elas?
ambas as interfaces parecem comparar objetos por igualdade, então quais são as principais diferenças entre elas?
Respostas:
IEquatable<T> para a igualdade.
IComparable<T> para fazer o pedido.
Além da resposta de Greg D:
Você pode implementar IComparablesem implementar IEquatablepara uma classe em que uma ordem parcial faça sentido e onde você definitivamente deseja que o consumidor deduza que, só porque CompareTo()retorna zero, isso não significa que os objetos são iguais (para qualquer coisa diferente de fins de classificação).
IComparableé totalmente inapropriado aqui. O que você tem é uma ordem muito particular que se aplica apenas a uma situação especial. Para tais situações, implementar um general IComparableé errado. É para isso que IComparerexistem. Por exemplo, as pessoas não podem ser ordenadas de forma significativa. Mas podem ser encomendados de acordo com o salário, o tamanho do sapato, a quantidade de sardas ou o peso. Portanto, implementaríamos IComparers diferentes para todos esses casos.
Conforme declarado na Página do MSDN para IEquatable :
A interface IComparable define o
CompareTométodo, que determina a ordem de classificação das instâncias do tipo de implementação. A interface IEquatable define oEqualsmétodo, que determina a igualdade das instâncias do tipo de implementação.
Equals vs. CompareTo
IComparable <T> define um método de comparação específico de tipo que pode ser usado para ordenar ou classificar objetos.
IEquatable <T> define um método generalizado que pode ser usado para implementar para determinar a igualdade.
Digamos que você tenha uma 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();.Mas isso lançará uma exceção.
O Framework não sabe como classificar esses objetos. Você precisa dizer como classificar a IComparableinterface de implementação .
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);
}
}
}
Isso classificará a matriz corretamente com o Sort()método.
Equals()método.var newPerson = new Person() { Name = "Person 1", Age = 34 };
var newPersonIsPerson1 = newPerson.Equals(p1);
Isso retornaráfalse porque o Equalsmétodo não sabe como comparar dois objetos. Portanto, você precisa implementar a IEquatableinterface e dizer ao framework como fazer a comparação. Estendendo o exemplo anterior, ficará assim.
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;
}
}
}
IEquatableusa um genérico <Person>e IComparablenão?
IComparablecorretamente. Você pode dar um exemplo significativo emCompareTo(…) == 0que não implique igualdade? Certamente não posso. Na verdade, o contrato de interface (conforme MSDN) exige queCompareTo(…) == 0implique igualdade. Para ser franco, em um caso como o seu, use umComparatorobjeto especial , não implementeIComparable.