Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using GetHashCode to test equality in Equals override

Tags:

c#

gethashcode

Is it ok to call GetHashCode as a method to test equality from inside the Equals override?

For example, is this code acceptable?

public class Class1
{
  public string A
  {
    get;
    set;
  }

  public string B
  {
    get;
    set;
  }

  public override bool Equals(object obj)
  {
    Class1 other = obj as Class1;
    return other != null && other.GetHashCode() == this.GetHashCode();
  }

  public override int GetHashCode()
  {
    int result = 0;
    result = (result ^ 397) ^ (A == null ? 0 : A.GetHashCode());
    result = (result ^ 397) ^ (B == null ? 0 : B.GetHashCode());
    return result;
  }
}
like image 537
Armbrat Avatar asked Nov 22 '10 18:11

Armbrat


2 Answers

The others are right; your equality operation is broken. To illustrate:

public static void Main()
{
    var c1 = new Class1() { A = "apahaa", B = null };
    var c2 = new Class1() { A = "abacaz", B = null };
    Console.WriteLine(c1.Equals(c2));
}

I imagine you want the output of that program to be "false" but with your definition of equality it is "true" on some implementations of the CLR.

Remember, there are only about four billion possible hash codes. There are way more than four billion possible six letter strings, and therefore at least two of them have the same hash code. I've shown you two; there are infinitely many more.

In general you can expect that if there are n possible hash codes then the odds of getting a collision rise dramatically once you have about the square root of n elements in play. This is the so-called "birthday paradox". For my article on why you shouldn't rely upon hash codes for equality, see:

Link

like image 187
Eric Lippert Avatar answered Oct 10 '22 00:10

Eric Lippert


No, it is not ok, because it's not

equality <=> hashcode equality.

It's just

equality => hashcode equality.

or in the other direction:

hashcode inequality => inequality.

Quoting http://msdn.microsoft.com/en-us/library/system.object.gethashcode.aspx:

If two objects compare as equal, the GetHashCode method for each object must return the same value. However, if two objects do not compare as equal, the GetHashCode methods for the two object do not have to return different values.

like image 21
ulrichb Avatar answered Oct 10 '22 01:10

ulrichb