GetHashCode for a class with a list object [duplicate]
Asked Answered
F

1

9

I have such a class:

public class Cycle
{
          public List<int> Edges
        {
            get;
            private set;
        }

        public override bool Equals(object obj)
        {
            Cycle cycle = (Cycle)obj;

            var list1 = cycle.Edges;
            var list2 = Edges;
            var same = list1.Except(list2).Count() == 0 &&
                       list2.Except(list1).Count() == 0;
            return same;

        }

        public override int GetHashCode()
        {
         //   return Edges.GetHashCode();
        }
} 

As you can see, if two Edge Lists are the same, then I deem the Cycles as the same.

The issue now is how to implement the GetHashCode()?

I tried Edges.GetHashCode(), but the problem is that two List<Cycle>, with the same Cycle object but different orders, will be deemed different, even though they should be the same.

Frigid answered 27/10, 2009 at 11:26 Comment(1)
Except is a set operation which gives you only the distinct items. If distinct items are all that matters then may be using HashSet<T> is a better choice. It has HashSet<T>.CreateSetComparer which does all this for free. In any case if you want to compare the distinct items only for equality, then !Any is more performant than Count == 0. Like !list1.Except(list2).Any() && !list2.Except(list1).Any();.Noelyn
B
17

You could do something like:

override int GetHashCode()
{
  return Edges.Distinct().Aggregate(0, (x,y) =>x.GetHashCode() ^ y.GetHashCode());
}

It is simple, but should consistent.

Bod answered 27/10, 2009 at 11:31 Comment(6)
+1 I don't see in which case it may fail for two equal lists, can you elaborate?Eckart
{1,2,3} vs {3,3,2,2,1,1}Bod
is OrderBy really required here? I think this should do: Edges.Distinct().Aggregate(0, (x, y) => x ^ y.GetHashCode()). Or (int)Edges.Distinct().Aggregate((x, y) => x.GetHashCode() ^ y.GetHashCode()) - the same, former being more concise.Noelyn
@nawfal: I cant recall :(Bod
OrderBy is not needed because of Commutativity and Associativity properties of the XOR (^) operator. Also the x.GetHashCode call in the aggregate is redundant. @Noelyn comment has the correct solution.Pino
@thepirat000: Removed it :)Bod

© 2022 - 2024 — McMap. All rights reserved.