Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net IEqualityComparer<;双倍>;宽容,;如何实现GetHashCode?_.net_Double_Hashcode_Iequalitycomparer_Epsilon - Fatal编程技术网

.net IEqualityComparer<;双倍>;宽容,;如何实现GetHashCode?

.net IEqualityComparer<;双倍>;宽容,;如何实现GetHashCode?,.net,double,hashcode,iequalitycomparer,epsilon,.net,Double,Hashcode,Iequalitycomparer,Epsilon,我正在实现一个可重用的DoubleEqualityComparer(带有一个自定义的容差:“epsilon”构造函数参数),以简化LINQ与double序列的使用。例如: bool myDoubleFound = doubles.Contains(myDouble, new DoubleEqualityComparer(epsilon: 0.01)); 实现GetHashCode的正确方法是什么?代码如下: public class DoubleEqualityComparer : IE

我正在实现一个可重用的DoubleEqualityComparer(带有一个自定义的容差:“epsilon”构造函数参数),以简化LINQ与double序列的使用。例如:

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)
        {
            // ?
        }
   }
公共类DoubleEqualityComparer:IEqualityComparer,IEqualityComparer
{
私有只读双ε;
公共双均衡比较器(双ε)
{
if(ε<0)
{
抛出新的ArgumentException(“epsilon不能为负”、“epsilon”);
}
this.epsilon=epsilon;
}
公共布尔等于(双x,双y)
{
返回系统.Math.Abs(x-y)

PS:我总是可以返回相同的值(例如:GetHashCode(double obj){return 0;})来强制调用Equals(double,double)方法(我知道性能不是很好),但我记得当比较器与字典一起使用时,这种解决方案会导致问题…

我不确定使用EqualityComparer是一种方法。因为比较对象不相等

也许你应该考虑使用一个简单的<代码>任何< /Cult>子句+一个实用方法:

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));
}
private static bool DoublesAreNearlyEquals(双d1,双d2,双ε=0.01D)
{
返回系统.Math.Abs(d1-d2)DoublesAreNearlyEquals(d,doubleToSearch));
}

我会在
GetHashCode
中抛出
NotSupportedException
,这样你就可以吃蛋糕了。这为您提供了在LINQ和其他方法中使用
IEqualityComparer
的便利,但保证了
GetHashCode
的任何使用都会失败。实际上,您可能会发现使用相等比较器的方式实际上并不需要调用
GetHashCode
。您甚至可以调用该类
NotHashableDoubleEqualityComparer
,以明确对调用方的限制。

您不应该这样做,因为它违反了传递性。有可能
a等于b
b等于c
a不等于c
。我有一个类似的问题,关于几何学中的点,出于所有意图和目的,如果点“足够接近”,则认为点是相等的,因为双倍的存储方式和公差是必需的,因此,如果相等,则哈希代码应生成相同的哈希,因此,当尝试使用字典跟踪和存储相同的点时,由于GetHashCode方法错误,哈希代码将崩溃。还有各种各样的原因,如果你找到了一个解决方案,字典会非常有用。否则,我将只编写一个自定义字典类,它的性能不太好,不能依赖于equals而不获取哈希代码。谢谢,你和Ani说服我不要使用IEqualityComparer,而是定义一个自定义接口(以及它的一组扩展方法,LINQ风格):公共接口ITolerable{boolArealMosteQual(tx,tyy)}IEqualityComparer很方便,因为有LINQ官方方法可以使用(不调用GetHashcode),但我不理解让它不实现是可怕的(也是危险的)@steve我不同意。IEqualityComparer(泛型和非泛型)接口的创建正是为了允许自定义相等对您意味着什么。例如,您可以为double创建一个自定义相等运算符,用于比较近似值,但使用原始的double.GetHashCode生成哈希。如果您想深入了解,我的建议是查看StringComparer类是如何实现的在参考源.HTH上编辑