Search code examples
c#hashcodecompareto

Does the CompareTo() method use GetHashCode()?


Does the method CompareTo() use GetHashCode() to define to the object a comparable (not the interface) number? If I do

MyObject.CompareTo(MyOtherObject.GetHashCode())

What will happen if I don't want to override the CompareTo() method ?


Solution

  • No, CompareTo does not / should not use GetHashCode to check for equality.

    They might (emphasis on might) use it to determine inequality, if the hash code is cached and thus cheaper to look at than comparing all the internal data, but equal hash codes does not necessarily mean equal objects.

    If you implement Equals and GetHashCode (you need to implement both or none), then here are the rules you should follow:

    1. If the two objects are equal (Equals returns true), they should produce the same hash code from GetHashCode. You can turn this rule on its head and say that if the two GetHashCode methods returns different values, Equals should return false.
    2. Note that the opposite does not hold. If Equals returns false, it is perfectly valid, though usually very unlikely, that GetHashCode returns the same value. Likewise, if GetHashCode returns the same value, it is perfectly valid, though again usually very unlikely, that Equals returns false. This is because of the Pigeonhole Principle (wikipedia link).
    3. Always use the same fields to check for equality and calculate the hash code
    4. Don't use mutable fields (if you can help it). If you do, make it very clear which fields will break the hashcode and equality checks. Stuffing mutable objects in a hashset or dictionary and the modifying them will break everything.

    If it's an object you're creating yourself then here are some rules:

    1. Implement CompareTo and IComparable<T> if you need ordering support. Don't implement CompareTo only to get equality checkes.
    2. Implement Equals, GetHashCode, and IEquatable<T> if you need equality checks.

    If it's an object you cannot modify, create:

    1. IComparer<T> to support ordering
    2. IEqualityComparer<T> to support equality checks

    Most collections or methods that will do ordering or equality checks allows you to specify an extra object that determines the rules for the ordering or equality checks, assuming that either the implementation built into the object is wrong (possibly in just this single scenario) or missing.

    Links to all the types: