IEqualityComparer <T>和IEquatable <T>有什么区别?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (31)

我想了解的场景中IEqualityComparer<T>,并IEquatable<T>应使用。两者的MSDN文档看起来非常相似。

提问于
用户回答回答于

IEqualityComparer<T>是一个对象的接口,用于在该类型的两个对象上执行比较T

IEquatable<T>是为了T能够比较自己和另一个类型的对象。

用户回答回答于

当决定是否使用IEquatable<T>或者IEqualityComparer<T>,可以问:

是否有一种首选的方法来测试两个T相等的实例,还是有几个同样有效的方法?

  • 如果只有一种方法来测试两个T相等的实例,或者如果有几种方法中的一种是首选的,那么IEquatable<T>这将是正确的选择:这个接口应该仅由其T自身实现,以便一个实例T具有内部知识如何将自己与另一个实例进行比较T
  • 另一方面,如果有几个同等合理的方法比较两个Ts是否相等,IEqualityComparer<T>看起来更合适:这个接口并不是要自己实现T,而是由其他“外部”类来实现。因此,在测试两个T相等的实例时,因为T对内部的平等没有内在的理解,所以您必须IEqualityComparer<T>根据您的具体要求明确选择执行测试的实例。

例:

让我们考虑这两种类型(它们应该具有价值语义):

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; }
}

为什么只有其中一种类型会继承IEquatable<>,而不是其他类型?

从理论上讲,只有一种比较两种实例类型的明智方式:如果两个实例中的属性XY属性相等,则它们是相等的。根据这种想法,两种类型都应该实施IEquatable<>,因为似乎没有其他有意义的方式进行平等测试。

这里的问题是,比较浮点数的平等可能无法按预期工作,由于细微的舍入错误。有几种不同的方法可以比较浮点数的近似性,每种方法都有特定的优点和折衷,你可能希望能够选择适合的方法。

sealed class DoublePointNearEqualityComparerByTolerance : IEqualityComparer<IDoublePoint>
{
    public DoublePointNearEqualityComparerByTolerance(double tolerance) { … }
    …
    public bool Equals(IDoublePoint a, IDoublePoint b)
    {
        return Math.Abs(a.X - b.X) <= tolerance  &&  Math.Abs(a.Y - b.Y) <= tolerance;
    }
    …
}

请注意,我链接到(上面)的页面明确指出,这个测试近乎平等有一些弱点。由于这是一个IEqualityComparer<T>实现,如果它不够好,可以将其交换出来。

扫码关注云+社区