替换System.Drawing.Point的GetHashCode()方法

时间:2015-05-26 21:12:58

标签: c# performance gdi+ gethashcode

如果您打算使用它来描述图像/位图中的“像素”,那么

System.Drawing.Point会有一个非常非常糟糕的GetHashCode方法:it is just XOR between the X and Y coordinates.

因此,对于具有2000x2000大小的图像,它具有荒谬的分数,因为只有对角线中的数字才会有一个不错的散列。

使用未经检查的乘法创建一个不错的GetHashCode方法非常容易,因为有些人已经提到here

但是我可以在GetHashCode中使用这种改进的HashSet方法吗? 我知道我可以创建自己的类/结构MyPoint并使用这些改进的方法实现它,但之后我会破坏项目中使用System.Drawing.Point的所有其他代码片段。

是否可以使用某种扩展方法等从System.Drawing.Point“覆盖”该方法?或者“告诉”HashSet使用其他功能而不是GetHashCode

目前,我正在使用SortedSet<System.Drawing.Point>与自定义IComparer<Point>来存储我的积分。当我想知道该集合是否包含Point时,我会调用BinarySearch。它比具有10000个冒号的集合中的HashSet<System.Drawing.Point>.Contains方法更快,但它没有像HashSet那样具有良好散列的速度。

1 个答案:

答案 0 :(得分:10)

您可以创建自己的实现IEqualityComparer<Point>的类,然后将该类提供给HashSet constructor

示例:

public class MyPointEqualityComparer : IEqualityComparer<Point>
{
    public bool Equals(Point p1, Point p2)
    {
        return p1 == p2; // defer to Point's existing operator==
    }

    public int GetHashCode(Point obj)
    {
        return /* your favorite hashcode function here */;
    }
}

class Program
{
    static void Main(string[] args)
    {
        // Create hashset with custom hashcode algorithm
        HashSet<Point> myHashSet = new HashSet<Point>(new MyPointEqualityComparer());

        // Same thing also works for dictionary
        Dictionary<Point, string> myDictionary = new Dictionary<Point, string>(new MyPointEqualityComparer());
    }
}