Creating the GetHashCode method in C#

Richie Cotton picture Richie Cotton · Jul 22, 2009 · Viewed 12.7k times · Source

What is the best way to create your own GetHashCode method for a class in C#? Suppose I have a simple class (which overrides the Equals method), as follows:

class Test
{
   public string[] names;

   public double[] values;

   public override bool Equals(object obj)
   {
      return (obj is Test) && this.Equals((Test)obj);
   }

   public bool Equals(Test t)
   {
      return names.Equals(t.names) && values.Equals(t.values);
   }
}

Should I use the default code for the GetHashCode method?

public override int GetHashCode()
{
   return base.GetHashCode();
}

Should I base the method on the contents of my class?

public override int GetHashCode()
{
   return names.GetHashCode() + values.GetHashCode() ;
}

Or should I do something else?

Answer

SLaks picture SLaks · Jul 22, 2009

System.Array does not override GetHashCode or Equals, so they use reference equality. Therefore, you shouldn't call them.

To implement GetHashCode, see this question.

To implement Equals, use the SequenceEqual extension method.

EDIT: On .Net 2.0, you'll have to write your own version of SequenceEqual, like this:

public static bool SequenceEquals<T>(IList<T> first, IList<T> second) {
    if (first == second) return true;
    if (first == null || second == null) return false;

    if (first.Count != second.Count) return false;

    for (int i = 0; i < first.Count; i++)
        if (!first[i].Equals(second[i]))
            return false;

    return true;
}

You could write it to take IEnumerable<T> instead of IList<T>, but it'd be somewhat slower because it wouldn't be able to exit early if the parameters have different sizes.