2

I've been experimenting with implementing Set equality (ie List comparisons where the order is irrelevant) and after reading SO questions like this and this, wrote the following simple extension:

    public static bool SetEqual<T>(this IEnumerable<T> enumerable, IEnumerable<T> other)
    {
        if (enumerable == null && other == null)
            return true;

        if (enumerable == null || other == null)
            return false;

        var setA = new HashSet<T>(enumerable);
        return setA.SetEquals(other);
    }

However, I came across a simple data structure for which this approach does not work, while Enumerable.SequenceEqual does.

    public class Test : IEquatable<Test>
    {
        public Guid Id { get; set; }
        public List<Test> RelatedTest { get; set; }

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

            return Equals((Test)obj);
        }

        public bool Equals(Test other)
        {
            if (ReferenceEquals(null, other)) return false;
            if (ReferenceEquals(this, other)) return true;

            return other.Id.Equals(Id) &&
                   RelatedTest.SetEqual(other.RelatedTest);
        }
    }

Given this object, this test succeeds:

    [Test]
    public void SequenceEqualTest()
    {
        var test1 = new List<Test> {new Test()};
        var test2 = new List<Test> {new Test() };

        Assert.That(test1.SequenceEqual(test2), Is.True);
    }

But this test fails:

    [Test]
    public void SetEqualTest()
    {
        var test1 = new List<Test> {new Test()};
        var test2 = new List<Test> {new Test()};

        Assert.That(test1.SetEqual(test2), Is.True);
    }

Does anyone have an explanation?

Community
  • 1
  • 1
Nik Pinski
  • 317
  • 3
  • 9

1 Answers1

6

Yes, you didn't override GetHashCode in your Test class, so the HashSet is unable to effectively group items into buckets according to possible equality. See this question for more details: Why is it important to override GetHashCode when Equals method is overridden?

Community
  • 1
  • 1
Jon
  • 16,212
  • 8
  • 50
  • 62