【发布时间】:2016-06-09 18:38:57
【问题描述】:
同样,这个示例是我实际问题的一个非常简化的版本,涉及用于 linq 分组的自定义比较器。我做错了什么?
下面的代码产生下面的结果 (1.2, 0), (4.1, 0), (4.1, 0), (1.1, 0),
但是我期待以下,因为 1.1 和 1.2 相差
class Program
{
static void Main(string[] args)
{
IEnumerable<Point> points = new List<Point> {
new Point(1.1, 0.0)
, new Point(4.1, 0.0)
, new Point(1.2, 0.0)
, new Point(4.1, 0.0)
};
foreach (var group in points.GroupBy(p => p, new PointComparer()))
{
foreach (var num in group)
Console.Write(num.ToString() + ", ");
Console.WriteLine();
}
Console.ReadLine();
}
}
class PointComparer : IEqualityComparer<Point>
{
public bool Equals(Point a, Point b)
{
return Math.Abs(a.X - b.X) < 1.0;
}
public int GetHashCode(Point point)
{
return point.X.GetHashCode()
^ point.Y.GetHashCode();
}
}
class Point
{
public double X;
public double Y;
public Point(double p1, double p2)
{
X = p1;
Y = p2;
}
public override string ToString()
{
return "(" + X + ", " + Y + ")";
}
}
【问题讨论】:
-
我认为您不能使用 group by 作为聚类点的解决方案。原因之一是 GetHashcode 必须为相等的项目返回相同的哈希值。
-
我知道这里没有这样做,但要注意的一件事是:不要使用
PointComparer.Default而不是new PointComparer()- 尽管文档说了什么,但它不会创建一个新的PointComparer,而是创建一个ObjectEqualityComparer`1。