c# – 如何使用Tolerance实现IEqualityComparer

这个问题类似于 the one here.

我们都知道PointF是什么,不是吗?这是数据结构:

public struct PointF
{
  public float X;
  public float Y;
}

如何实现IEqualityComparer< PointF>宽容?假设我的Equals代码是这样的

public const float Epsilon = 0.01; //say
public bool Equals(PointF pt1,PointF pt2)
{
   return Math.Abs(pt1.X-pt2.X)<Epsilon && Math.Abs(pt1.Y-pt2.Y)<Epsilon;
}

问题:如何实现正确的GetHashCode,以便对于PointF的字典,我将正确访问该元素?

我几天头脑裂开但仍然无法找到满意的解决方案.

解决方法

您可以将点放在网格中,而不是通过距离定义公差.
如果两个点在同一个单元格中,则它们被认为是相等的并且具有相同的哈希码.
public bool Equals(PointF pt1,PointF pt2)
{
   return GetCell(pt1.X) == GetCell(pt2.X)
       && GetCell(pt1.Y) == GetCell(pt2.Y);
}

public int GetHashCode(PointF pt)
{
   return GetCell(pt.X) ^ GetCell(pt.Y);
}

private static int GetCell(float f)
{
    return (int)(f / 10); // cell size is 10 pixels
}

论文:没有满足您要求的Equals和GetHashCode的实现.

证明:考虑以下三点,A,B和C:

Illustration http://i45.tinypic.com/10wlmkx.png

根据您的要求,

Equals(A,B) == true              // (i)
Equals(B,C) == true              // (ii)
Equals(A,C) == false             // (iii)
GetHashCode(A) == GetHashCode(B)  // (iv)
GetHashCode(B) == GetHashCode(C)  // (v)
GetHashCode(A) != GetHashCode(C)  // (vi)

但是从(iv)和(v)开始

GetHashCode(A) == GetHashCode(C)

从而

Equals(A,C) == true

这与(iii)和(vi)相矛盾.

由于Equals和GetHashCode不能为相同的参数返回不同的值,因此没有满足您要求的实现.证明完毕

相关文章

原文地址:http://msdn.microsoft.com/en-us/magazine/cc163...
前言 随着近些年微服务的流行,有越来越多的开发者和团队所采...
最近因为比较忙,好久没有写博客了,这篇主要给大家分享一下...
在多核CPU在今天和不久的将来,计算机将拥有更多的内核,Mic...
c语言输入成绩怎么判断等级
字符型数据在内存中的存储形式是什么