ambas interfaces parecen comparar objetos por igualdad, entonces, ¿cuáles son las principales diferencias entre ellos?
ambas interfaces parecen comparar objetos por igualdad, entonces, ¿cuáles son las principales diferencias entre ellos?
Respuestas:
IEquatable<T>
por la igualdad.
IComparable<T>
para ordenar.
Además de la respuesta de Greg D:
Puede implementar IComparable
sin implementar IEquatable
para una clase donde un orden parcial tiene sentido, y donde definitivamente quiere que el consumidor infiera que solo porque CompareTo()
devuelve cero, esto no implica que los objetos sean iguales (para cualquier otra cosa que no sea la clasificación).
IComparable
es totalmente inapropiado aquí. Lo que tiene es un pedido muy particular que solo se aplica en una situación especial. Para tales situaciones, implementar un general IComparable
está mal. Para eso IComparer
están las s. Por ejemplo, no se puede ordenar a las personas de manera significativa. Pero se pueden ordenar según su salario, la talla de sus zapatos, el número de sus pecas o su peso. Por lo tanto, implementaríamos diferentes IComparer
s para todos estos casos.
Como se indica en la página de MSDN para IEquatable :
La interfaz IComparable define el
CompareTo
método, que determina el orden de clasificación de las instancias del tipo de implementación. La interfaz IEquatable define elEquals
método, que determina la igualdad de instancias del tipo de implementación.
Equals
vs. CompareTo
IComparable <T>
define un método de comparación específico de tipo que se puede utilizar para ordenar u ordenar objetos.
IEquatable <T>
define un método generalizado que se puede utilizar para implementar para determinar la igualdad.
Digamos que tienes clase 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();
.Pero esto arrojará una excepción.
Framework no sabe cómo ordenar estos objetos. Necesita decir cómo ordenar la implementación de la IComparable
interfaz.
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);
}
}
}
Esto ordenará la matriz correctamente con el Sort()
método.
Equals()
método.var newPerson = new Person() { Name = "Person 1", Age = 34 };
var newPersonIsPerson1 = newPerson.Equals(p1);
Esto regresaráfalse
porque el Equals
método no sabe cómo comparar dos objetos. Por lo tanto, debe implementar la IEquatable
interfaz y decirle al marco cómo hacer la comparación. Ampliando el ejemplo anterior, se verá así.
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
utiliza un genérico <Person>
y IComparable
no?
IComparable
correctamente. Se puede llegar a un ejemplo significativo, dondeCompareTo(…) == 0
no no implica la igualdad? Ciertamente no puedo. De hecho, el contrato de interfaz (según MSDN) requiere que esoCompareTo(…) == 0
implique igualdad. Para decirlo sin rodeos, en un caso como el suyo, use unComparator
objeto especial , no lo implementeIComparable
.