使用ContainsExactly比较对象集合

时间:2018-01-12 19:13:50

标签: c# .net contains iequatable

我试图比较两个在各自集合中具有完全相同对象的对象集合。我为ContainsExactly编写了一个扩展方法来执行此操作。

然而,我遇到的问题是它们的集合虽然不一样。以下是测试代码:

RewriteEngine On
RewriteRule ^([A-Za-z0-9-]+)/([A-Za-z0-9-]+)$   index.php?apple=$1&bee=$2  [L]

那么我有我的对象:

public static bool ContainsExactly<T>(this List<T> set1, List<T> set2)
    {
        if (set1.Count != set2.Count)
            return false;

        //var isEqual = new HashSet<T>(set1).SetEquals(set2); original test just returned isEqual
        var result = set1.Except(set2);            

        return !result.Any(); //still yields both collections in result


    }

当我运行我的测试时,他们仍然会返回false:

public class ReferenceClassObjectTest : IEquatable<ReferenceClassObjectTest>
    {
        public int Id { get; set; }
        public TestObject TestObject { get; set; }


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

            return Equals((ReferenceClassObjectTest)obj);
        }

        public bool Equals(ReferenceClassObjectTest other)
        {
            var casted = other as ReferenceClassObjectTest;

            if (casted == null)
                return false;

            return Id == casted.Id && TestObject == casted.TestObject;
        }

        public override int GetHashCode()
        {
            var hash = Id;                   

            if(TestObject != null)
            {
                hash = (hash * 397) ^ TestObject.GetHashCode();
            }
            else
            {
                hash = (hash * 397);
            }

            return hash;

        }
    }

public class TestObject : IEquatable<TestObject>
    {
        public int Id { get; set; }

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

            return Equals((TestObject)obj);
        }

        public bool Equals(TestObject other)
        {
            var casted = other as TestObject;

            if (casted == null)
                return false;

            return Id == casted.Id;
        }

        public override int GetHashCode()
        {
            var hashCode = Id;
            hashCode = (hashCode * 397);
            return hashCode;
        }
    }

有关为什么即使重写GetHashCode()也无法正确比较的任何见解?

我认为HashSet.SetEquals()会考虑我对GetHashCode()的覆盖,当我在列表中的两个单独对象上调用get hashcode时,我会得到相同的哈希:。

SET3 [1] .TestObject.GetHashCode() 1191

SET2 [1] .TestObject.GetHashCode() 1191

SET2 [0] .GetHashCode() 663

SET3 [0] .GetHashCode() 663

1 个答案:

答案 0 :(得分:1)

您对Equals ReferenceClassObjectTest的定义使用==而不是Equals调用TestObject,因此您正在比较TestObject的引用标识}}第

将其更改为:

return Id == other.Id && TestObject.Equals(other.TestObject);

或者,如果您认为TestObject是一个不可变对象(因为它有一个public int字段,我不这么认为)您应该实现operator==来调用Equals。< / p>