的IEqualityComparer 用宽容; 如何实现GetHashCode的?(IEqu

2019-09-18 18:11发布

我执行一个可重复使用的DoubleEqualityComparer(使用自定义公差:在“小量”的构造函数参数),以缓解LINQ的使用与双序列。 例如:

bool myDoubleFound = doubles.Contains(myDouble, new DoubleEqualityComparer(epsilon: 0.01));

什么是执行的GetHashCode正确的方式? 下面的代码:

   public class DoubleEqualityComparer : IEqualityComparer<double>, IEqualityComparer<double?>
    {
        private readonly double epsilon;

        public DoubleEqualityComparer(double epsilon)
        {
            if (epsilon < 0)
            {
                throw new ArgumentException("epsilon can't be negative", "epsilon");
            }

            this.epsilon = epsilon;
        }

        public bool Equals(double x, double y)
        {
            return System.Math.Abs(x - y) < this.epsilon;
        }

        public int GetHashCode(double obj)
        {
            // ?
        }
   }

PS:我可以随时返回相同的值(例如:GetHashCode的(双OBJ){返回0;})总是强制调用的equals(双,双)方法(不是很高性能的,我知道),但我记得这解决造成问题时,比较器与字典使用...

Answer 1:

我不知道使用EqualityComparer是要走的路。 由于比较的对象不是平等的。

也许你应该考虑使用一个简单的Any条款+的实用方法:

private static bool DoublesAreNearlyEquals(double d1, double d2, double epsilon = 0.01D)
{
    return System.Math.Abs(d1 - d2) < this.epsilon;
}

private void foo()
{
    var myDoubles = Getdoubles();
    var doubleToSearch = 42D;
    var result = myDoubles.Any(d=>DoublesAreNearlyEquals(d, doubleToSearch));
}


Answer 2:

我会抛出NotSupportedExceptionGetHashCode ,所以你可以有你的蛋糕和熊掌兼得。 这使您具有方便IEqualityComparer在LINQ等方法,但可以保证的任何使用GetHashCode炸毁。 在实践中,你可能会发现你使用相等比较从来没有真正的路需要GetHashCode调用。 你甚至可以调用这个类NotHashableDoubleEqualityComparer是关于限制主叫方超清晰。



文章来源: IEqualityComparer with a tolerance; how to implement GetHashCode?