Search code examples
.nethashgethashcode

Default implementation for Object.GetHashCode()


How does the default implementation for GetHashCode() work? And does it handle structures, classes, arrays, etc. efficiently and well enough?

I am trying to decide in what cases I should pack my own and in what cases I can safely rely on the default implementation to do well. I don't want to reinvent the wheel, if at all possible.


Solution

  • namespace System {
        public class Object {
            [MethodImpl(MethodImplOptions.InternalCall)]
            internal static extern int InternalGetHashCode(object obj);
    
            public virtual int GetHashCode() {
                return InternalGetHashCode(this);
            }
        }
    }
    

    InternalGetHashCode is mapped to an ObjectNative::GetHashCode function in the CLR, which looks like this:

    FCIMPL1(INT32, ObjectNative::GetHashCode, Object* obj) {  
        CONTRACTL  
        {  
            THROWS;  
            DISABLED(GC_NOTRIGGER);  
            INJECT_FAULT(FCThrow(kOutOfMemoryException););  
            MODE_COOPERATIVE;  
            SO_TOLERANT;  
        }  
        CONTRACTL_END;  
    
        VALIDATEOBJECTREF(obj);  
    
        DWORD idx = 0;  
    
        if (obj == 0)  
            return 0;  
    
        OBJECTREF objRef(obj);  
    
        HELPER_METHOD_FRAME_BEGIN_RET_1(objRef);        // Set up a frame  
    
        idx = GetHashCodeEx(OBJECTREFToObject(objRef));  
    
        HELPER_METHOD_FRAME_END();  
    
        return idx;  
    }  
    FCIMPLEND
    

    The full implementation of GetHashCodeEx is fairly large, so it's easier to just link to the C++ source code.