简体   繁体   English

等于和GetHashCode混淆

[英]Equals and GetHashCode confusion

I am trying to implement an immutable Point class where two Point instances are considered equal if they have the same Coordinate s. 我正在尝试实现一个不变的Point类,如果两个Point实例具有相同的Coordinate则认为它们是相等的。 I am using Jon Skeet's implementation of a Coordinate value type. 我正在使用Jon Skeet的Coordinate值类型的实现

For comparing equality of Point s I have also inherited EqualityComparer<Point> and IEquatable<Point> and I have a unit test as below: 为了比较Point的相等性,我还继承了EqualityComparer<Point>IEquatable<Point>并且具有如下单元测试:

Point.cs: Point.cs:

public class Point : EqualityCompararer<Point>, IEquatable<Point>
{
    public Coordinate Coordinate { get; private set; }

    // EqualityCompararer<Point>, IEquatable<Point> methods and other methods
}

PointTests.cs: PointTests.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);
}

Now I am really confused by the 3 interface/abstract methods that I must implement. 现在,我对必须实现的3种接口/抽象方法感到非常困惑。 These are: 这些是:

  • IEquatable<Point>.Equals(Point other)
  • EqualityComparer<Point>.Equals(Point x, Point y)
  • EqualityComparer<Point>.GetHashCode(Point obj)

And since I have overriden IEquatable<Point>.Equals , according to MSDN I must also implement: 而且由于我已重写IEquatable<Point>.Equals ,因此根据MSDN我还必须实现:

  • Object.Equals(object obj)
  • Object.GetHashCode(object obj)

Now I am really confused about all the Equals and GetHashCode methods that are required to satisfy my unit test (Reference equality should return false and value equality should return true for point1 and point2 ). 现在,我对满足我的单元测试所需的所有EqualsGetHashCode方法确实感到困惑(对于point1point2引用相等应返回false,值相等应返回true)。

Can anyone explain a bit further about Equals and GetHashCode ? 任何人都可以进一步解释EqualsGetHashCode吗?

Because Coordinate already implments GetHashCode() and Equals(Coordinate) for you it is actually quite easy, just use the underlying implmentation 由于协调中心已经为您实现了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);
    }
}

the IEquatable<Point> is unnecessary as all it does is save you a extra cast. IEquatable<Point>是不必要的,因为它所做的就是为您节省了额外的演员。 It is mainly for struct type classes to prevent the boxing of the struct in to the object passed in to bool Equals(object) . 它主要用于struct类型的类,以防止该结构的拳击到object传递到bool Equals(object)

Equals : Used to check if two objects are equal. 等于 :用于检查两个对象是否相等。 There are several checks for equality (by value, by reference), and you really want to have a look at the link to see how they work, and the pitfalls when you don't know who is overriding them how. 有几种检查是否相等的方法(按值,按引用),您真的想看看链接以了解它们如何工作,以及在不知道谁在压制它们的情况下的陷​​阱。

GetHashCode : GetHashCode
A hash code is a numeric value that is used to insert and identify an object in a hash-based collection such as the Dictionary class, the Hashtable class, or a type derived from the DictionaryBase class. 哈希码是一个数字值,用于在基于哈希的集合中插入和标识对象,例如Dictionary类,Hashtable类或从DictionaryBase类派生的类型。 The GetHashCode method provides this hash code for algorithms that need quick checks of object equality. GetHashCode方法为需要快速检查对象相等性的算法提供此哈希码。

Let's assume you're having two huge objects with heaps of objects inside, and that comparing them might take a very long time. 假设您有两个巨大的对象,内部有很多对象,并且比较它们可能需要很长时间。 And then you have a collection of those objects, and you need to compare them all. 然后,您具有这些对象的集合,并且需要将它们全部进行比较。 As the definitions say, GetHashCode will return a simple number you can compare if you don't want to compare the two objects. 就像定义中所说的,如果不想比较两个对象,GetHashCode将返回一个可以比较的简单数字。 (and assuming you implemented them correctly, two different objects will not have the same hashcode, while objects who are supposed to be "equal" will). (并假设您正确实现了它们,则两个不同的对象将不会具有相同的哈希码,而假定为“相等”的对象将具有相同的哈希码)。

And if you want Jon Skeet's opinion on something similar, look here . 如果您希望乔恩·斯凯特(Jon Skeet)对类似内容有意见,请看这里

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM