简体   繁体   English

HashSet不会删除具有覆盖的相等的重复项

[英]HashSet doesn't remove dupes with overridden equality

I have a class Pair , which needs to have an overridden equality operator due to the two values it stores being interchangeable, the code is this 我有一个Pair类,由于它存储的两个值是可互换的,因此需要一个重写的等式运算符,代码是这样的

Pair.cs Pair.cs

public class Pair
    {
        protected bool Equals(Pair other)
        {
            return (Equals(A, other.A) && Equals(B, other.B)) || (Equals(A, other.B) && Equals(B, other.A));
        }

        public override bool Equals(object obj)
        {
            if (ReferenceEquals(null, obj)) return false;
            if (ReferenceEquals(this, obj)) return true;
            return obj.GetType() == this.GetType() && Equals((Pair) obj);
        }

        public override int GetHashCode()
        {
            unchecked
            {
                return ((A != null ? A.GetHashCode() : 0)*397) ^ (B != null ? B.GetHashCode() : 0);
            }
        }

        public readonly Collision A, B;

        public Pair(Collision a, Collision b)
        {
            A = a;
            B = b;
        }

        public static bool operator ==(Pair a, Pair b)
        {
            if (ReferenceEquals(a, b))
                return true;

            if ((object)a == null || (object)b == null)
                return false;

            return (a.A == b.A && a.B == b.B) || (a.A == b.B && a.B == b.A);
        }

        public static bool operator !=(Pair a, Pair b)
        {
            return !(a == b);
        }
    }

I had ReSharper add the Equals and GetHashCode methods, I know Equals is ok, but is GetHashCode outputting the correct value? 我让ReSharper添加了EqualsGetHashCode方法,我知道Equals可以,但是GetHashCode输出正确的值吗?

I have a HashSet<Pair> that I use to store the pairs, and I need to ensure there are no duplications in this list, however when I add the pairs to a HashSet it doesn't remove the duplicates. 我有一个用于存储对的HashSet<Pair> ,我需要确保此列表中没有重复项,但是当我将对添加到HashSet它不会删除重复项。

Just for clarification, this would be a duplicate: 只是为了澄清,这将是重复的:

Pair a = new Pair(objecta, objectb);
Pair b = new Pair(objectb, objecta);
HashSet<Pair> pairs = new HashSet<Pair>();
pairs.Add(a);
pairs.Add(b);
return pairs.Count(); //Count() returns 2 when it should be 1!

Your GetHashCode implementation does not return the same value for (A, B) and (B, A). 您的GetHashCode实现不会为(A,B)和(B,A)返回相同的值。 The HashSet checks if it already contains a given hash at the moment of insertion. HashSet在插入时检查它是否已经包含给定的哈希。 If it doesn't, then the object will be considered new. 如果不是,则该对象将被视为新对象。

If you correct your GetHashCode , then at the moment of inserting the second Pair the HashSet will see that the hash code already exists and verify equality with the other objects sharing the same hash code. 如果您更正了GetHashCode ,则在插入第二PairHashSet将看到哈希码已经存在,并验证与共享相同哈希码的其他对象是否相等。

Just remove this: *397 只需删除:* 397

If they are considered duplicates, they must return the same int from GetHashCode() . 如果它们被视为重复项,则必须从GetHashCode()返回相同的int (However, if they are not considered duplicates they are still allowed to return the same int, that will only affect performance). (但是,如果不将它们视为重复项,则仍允许它们返回相同的int,这只会影响性能)。

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

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