2

我有一个类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);
        }
    }

我让 ReSharper 添加了EqualsandGetHashCode方法,我知道没问题Equals,但是GetHashCode输出的是正确的值吗?

我有一个HashSet<Pair>用于存储对的 a,我需要确保此列表中没有重复项,但是当我将这些对添加到 aHashSet时,它不会删除重复项。

只是为了澄清,这将是重复的:

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!
4

2 回答 2

3

您的GetHashCode实现不会为 (A, B) 和 (B, A) 返回相同的值。检查它HashSet是否在插入时已经包含给定的哈希。如果不是,则该对象将被视为新对象。

如果您更正您的GetHashCode,那么在插入第二个Pair时,HashSet将看到哈希码已经存在,并验证与共享相同哈希码的其他对象的相等性。

于 2013-06-04T02:03:33.140 回答
2

删除这个:*397

如果它们被认为是重复的,它们必须从 GetHashCode() 返回相同的 int。(但是,如果它们不被认为是重复的,它们仍然可以返回相同的 int,这只会影响性能)。

于 2013-06-04T02:01:46.550 回答