IEqualityComparer <T>和IEquatable <T>有什么区别?
我想了解应该使用IEqualityComparer<T>和IEquatable<T>的场景。 两个MSDN文档看起来非常相似。 
  IEqualityComparer<T>是一个对象的接口,用于对Ttypes的两个对象执行比较。 
  IEquatable<T>用于Ttypes的对象,以便它可以将自己与另一个对比。 
 当决定是否使用IEquatable<T>或IEqualityComparer<T> ,可以问: 
是否有一种testing
T两个实例是否相等的首选方法,还是有几个同样有效的方法?
- 
如果只有一种方法来testing T两个实例是否相等,或者有几个方法中的一个是优先的,那么IEquatable<T>就是正确的select:这个接口应该只由T本身实现,这样一个T实例具有如何将自身与T另一个实例进行比较的内部知识。
- 
另一方面,如果有几个同等合理的方法比较两个 Ts是否相等,IEqualityComparer<T>看起来更合适:这个接口并不意味着由T本身实现,而是由其他“外部”类实现。 因此,在testingT两个实例是否相等时,由于T没有内部对等的理解,因此必须根据您的具体要求明确select执行testing的IEqualityComparer<T>实例。
例:
让我们考虑这两种types(应该是有价值的语义 ):
 interface IIntPoint : IEquatable<IIntPoint> { int X { get; } int Y { get; } } interface IDoublePoint // does not inherit IEquatable<IDoublePoint>; see below. { double X { get; } double Y { get; } } 
 为什么只有这些types之一会inheritanceIEquatable<> ,而不是其他的? 
 理论上,只有一种比较两种情况的明智方式:如果两种情况下的X和Y属性相等,则它们是相等的。 按照这个思路,这两种types都应该实现IEquatable<> ,因为似乎没有其他有意义的方法进行平等testing。 
这里的问题是,由于细微的舍入错误 , 比较浮点数相等性可能无法按预期工作 。 有几种不同的方法比较近似平等的浮点数,每种方法都有特定的优点和折衷,您可能希望能够select适合自己的方法。
 sealed class DoublePointNearEqualityComparerByTolerance : IEqualityComparer<IDoublePoint> { public DoublePointNearEqualityComparerByTolerance(double tolerance) { … } … public bool Equals(IDoublePoint a, IDoublePoint b) { return Math.Abs(aX - bX) <= tolerance && Math.Abs(aY - bY) <= tolerance; } … } 
 请注意,我链接到(上面)页面明确指出,这种testing近乎平等有一些弱点。 由于这是一个IEqualityComparer<T>实现,所以如果对于您的目的来说不够好,您可以将其交换出来。 
 你已经有了它们的基本定义。 简而言之,如果在类T上实现了IEquatable<T> ,那么IEquatable<T>types的对象上的Equals方法会告诉您对象本身(正在testing的是否相等)与另一个相同typesT实例相同。 而IEqualityComparer<T>用于testingIEqualityComparer<T>的任何两个实例的相等性,通常在T实例的范围之外。 
 至于他们是什么,可以混淆起初。 从定义中应该清楚,因此IEquatable<T> (在T类本身中定义)应该成为表示对象/实例唯一性的事实标准。  HashSet<T> , Dictionary<T, U> (考虑GetHashCode也被重写), Contains List<T>等等。 在T上实现IEqualityComparer<T>并不能帮助上面提到的一般情况。 随后,除了IEquatable<T>任何其他类实现IEquatable<T>价值不大。 这个: 
 class MyClass : IEquatable<T> 
很less有道理。
另一方面
 class T : IEquatable<T> { //override ==, !=, GetHashCode and non generic Equals as well public bool Equals(T other) { //.... } } 
是应该如何做的。
  IEqualityComparer<T>在需要自定义相等性validation时非常有用,但不是一般规则。 例如,在某Person某个阶层,你可能需要根据他们的年龄来testing两个人的平等。 在这种情况下,你可以这样做: 
 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; } } 
要testing它们,请尝试
 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 
 同样, IEqualityComparer<T>上的IEqualityComparer<T>没有任何意义。 
 class Person : IEqualityComparer<Person> 
这确实有效,但对眼睛看起来并不好,并且打败了逻辑。
  通常你需要的是IEquatable<T> 。  理想情况下,您可以只有一个IEquatable<T>而多个IEqualityComparer<T>可能基于不同的标准。 
  IEqualityComparer<T>和IEquatable<T>完全类似于Comparer<T>和IComparable<T> ,它们用于比较而不是等同;  这里的一个很好的线程,我写了相同的答案:) 
IEqualityComparer用于当两个对象的等式是在外部实现的时候,例如,如果你想为两个没有源的types定义一个比较器,或者两个事物之间的相等只在某些有限的情况下才有意义。
IEquatable是为了实现对象本身(被比较的是相等的)。
 一个比较两个T s。 另一个可以与其他T比较。 通常,你只需要一次使用一个,而不是两个。