Ya tienes la definición básica de lo que son . En resumen, si implementa IEquatable<T>
en clase T
, el Equals
método en un objeto de tipo T
le dice si el objeto mismo (el que se está probando para la igualdad) es igual a otra instancia del mismo tipo T
. Mientras que, IEqualityComparer<T>
es para probar la igualdad de dos instancias de T
, típicamente fuera del alcance de las instancias de T
.
En cuanto a lo que son, puede ser confuso al principio. A partir de la definición, debe quedar claro que, por lo tanto, IEquatable<T>
(definido en la T
propia clase ) debería ser el estándar de facto para representar la unicidad de sus objetos / instancias. HashSet<T>
, Dictionary<T, U>
(teniendo en GetHashCode
cuenta que también se anula), Contains
en List<T>
etc. haga uso de esto. Implementar IEqualityComparer<T>
en T
no ayuda a los casos generales mencionados anteriormente. Posteriormente, hay poco valor para implementar IEquatable<T>
en cualquier otra clase que no sea T
. Esta:
class MyClass : IEquatable<T>
Rara vez tiene sentido.
Por otra parte
class T : IEquatable<T>
{
//override ==, !=, GetHashCode and non generic Equals as well
public bool Equals(T other)
{
//....
}
}
así es como debe hacerse.
IEqualityComparer<T>
puede ser útil cuando necesita una validación personalizada de igualdad, pero no como una regla general. Por ejemplo, en una clase de Person
en algún momento, es posible que deba probar la igualdad de dos personas en función de su edad. En ese caso puedes hacer:
class Person
{
public int Age;
}
class AgeEqualityTester : IEqualityComparer<Person>
{
public bool Equals(Person x, Person y)
{
return x.Age == y.Age;
}
public int GetHashCode(Person obj)
{
return obj.Age.GetHashCode;
}
}
Para probarlos, intente
var people = new Person[] { new Person { age = 23 } };
Person p = new Person() { age = 23 };
print people.Contains(p); //false;
print people.Contains(p, new AgeEqualityTester()); //true
Del mismo modo IEqualityComparer<T>
en T
que no tiene sentido.
class Person : IEqualityComparer<Person>
Es cierto que esto funciona, pero no se ve bien a los ojos y derrota la lógica.
Por lo general, lo que necesitas es IEquatable<T>
. También, idealmente, puede tener solo uno, IEquatable<T>
mientras que múltiples IEqualityComparer<T>
es posible según diferentes criterios.
Los IEqualityComparer<T>
y IEquatable<T>
son exactamente análogos a Comparer<T>
y IComparable<T>
que se utilizan para fines de comparación en lugar de igualar; un buen hilo aquí donde escribí la misma respuesta :)
EqualityComparer<T>
lugar de implementar la interfaz "porqueEqualityComparer<T>
prueba la igualdad usandoIEquatable<T>