您已经了解了它们是什么的基本定义。简而言之,如果您在类T 上实现IEquatable<T>,则Equals 类型对象上的Equals 方法会告诉您对象本身(正在测试相等性的对象)是否等于相同的另一个实例输入T。而IEqualityComparer<T> 用于测试T 的任何两个实例的相等性,通常在T 的实例范围之外。
至于它们的用途,起初可能会令人困惑。从定义中应该很清楚,因此IEquatable<T>(在类T 本身中定义)应该是表示其对象/实例的唯一性的事实标准。 HashSet<T>、Dictionary<T, U>(考虑到GetHashCode 也被覆盖)、Contains 上的List<T> 等都利用了这个。在T 上实现IEqualityComparer<T> 对上述一般情况没有帮助。随后,在T 以外的任何其他类上实现IEquatable<T> 几乎没有价值。这个:
class MyClass : IEquatable<T>
很少有意义。
另一方面
class T : IEquatable<T>
{
//override ==, !=, GetHashCode and non generic Equals as well
public bool Equals(T other)
{
//....
}
}
是应该怎么做的。
IEqualityComparer<T> 在您需要自定义相等性验证时很有用,但不是一般规则。例如,在 Person 的某个类中,您可能需要根据两个人的年龄来测试他们是否相等。在这种情况下,您可以这样做:
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;
}
}
要测试它们,请尝试
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
T 上的 IEqualityComparer<T> 同样没有意义。
class Person : IEqualityComparer<Person>
的确,这可行,但看起来不太好,并且不符合逻辑。
通常你需要的是IEquatable<T>。理想情况下,您只能拥有一个IEquatable<T>,而多个IEqualityComparer<T> 可以根据不同的标准。
IEqualityComparer<T> 和IEquatable<T> 与Comparer<T> 和IComparable<T> 完全相同,它们用于比较而不是等同;一个很好的线程here 我写了相同的答案:)