我正在尝试实现一个不可变的Point
类,如果两个Point
实例具有相同的Coordinate
s,则认为它们是相等的。我正在使用Jon Skeet的Coordinate
Point
值类型。
为了比较EqualityComparer<Point>
的平等性,我还继承了IEquatable<Point>
和public class Point : EqualityCompararer<Point>, IEquatable<Point>
{
public Coordinate Coordinate { get; private set; }
// EqualityCompararer<Point>, IEquatable<Point> methods and other methods
}
,我有一个单元测试如下:
Point.cs:
[Fact]
public void PointReferencesToSamePortalAreNotEqual()
{
var point1 = new Point(22.0, 24.0);
var point2 = new Point(22.0, 24.0);
// Value equality should return true
Assert.Equal(point1, point2);
// Reference equality should return false
Assert.False(point1 == point2);
}
PointTests.cs:
IEquatable<Point>.Equals(Point other)
现在我对我必须实现的3个接口/抽象方法感到困惑。这些是:
EqualityComparer<Point>.Equals(Point x, Point y)
EqualityComparer<Point>.GetHashCode(Point obj)
IEquatable<Point>.Equals
由于我已覆盖Object.Equals(object obj)
,根据implementation我还必须实施:
Object.GetHashCode(object obj)
Equals
现在我对满足单元测试所需的所有GetHashCode
和point1
方法感到困惑(引用相等性应该返回false,值相等应该对point2
返回true并且Equals
)。
有人可以进一步解释GetHashCode
和{{1}}吗?
答案 0 :(得分:1)
因为Coordinate已经为您实现了GetHashCode()
和Equals(Coordinate)
,所以实际上非常简单,只需使用基础实施
public class Point : IEquatable<Point>
{
public Coordinate Coordinate { get; private set; }
public override int GetHashCode()
{
return Coordinate.GetHashCode();
}
public override bool Equals(object obj)
{
return this.Equals(obj as Point);
}
public bool Equals(Point point)
{
if(point == null)
return false;
return this.Coordinate.Equals(point.Coordinate);
}
}
IEquatable<Point>
是不必要的,因为它只是为你节省额外的演员。它主要用于struct
类型类,以防止将结构装入传递给object
的{{1}}。
答案 1 :(得分:0)
Equals: 用于检查两个对象是否相等。有几个相等的检查(按价值,通过参考),你真的想看一下链接,看看它们是如何工作的,当你不知道是谁压倒它们时会有什么陷阱。
GetHashCode:
哈希码是一个数值,用于插入和标识基于散列的集合中的对象,例如Dictionary类,Hashtable类或从DictionaryBase类派生的类型。 GetHashCode方法为需要快速检查对象相等性的算法提供此哈希代码。
让我们假设你有两个巨大的物体,里面堆满了物体,比较它们可能需要很长时间。然后你有这些对象的集合,你需要将它们全部进行比较。正如定义所说,如果您不想比较两个对象,GetHashCode将返回一个可以比较的简单数字。 (并假设您正确实现了它们,两个不同的对象将不具有相同的哈希码,而应该是“相等”的对象将)。
如果你想要Jon Skeet对类似内容的看法,请查看here。