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.

Graviton
  • 81,782
  • 146
  • 424
  • 602
  • `Except` is a set operation which gives you only the distinct items. If distinct items are all that matters then may be using `HashSet` is a better choice. It has `HashSet.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();`. – nawfal Aug 11 '14 at 06:13

1 Answers1

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.

leppie
  • 115,091
  • 17
  • 196
  • 297
  • +1 I don't see in which case it may fail for two equal lists, can you elaborate? – vgru Oct 27 '09 at 11:43
  • {1,2,3} vs {3,3,2,2,1,1} – leppie Oct 27 '09 at 13:43
  • 1
    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. – nawfal Aug 11 '14 at 06:16
  • 1
    @nawfal: I cant recall :( – leppie Aug 11 '14 at 17:53
  • 1
    OrderBy is not needed because of Commutativity and Associativity properties of the XOR (^) operator. Also the x.GetHashCode call in the aggregate is redundant. @nawfal comment has the correct solution. – thepirat000 Nov 25 '14 at 22:52
  • @thepirat000: Removed it :) – leppie Nov 26 '14 at 04:51