.net - Object.GetHashCode()的默認實現




2 Answers

namespace System {
    public class Object {
        [MethodImpl(MethodImplOptions.InternalCall)]
        internal static extern int InternalGetHashCode(object obj);

        public virtual int GetHashCode() {
            return InternalGetHashCode(this);
        }
    }
}

InternalGetHashCode被映射到CLR中的ObjectNative :: GetHashCode函數,如下所示:

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

GetHashCodeEx的完整實現是相當大的,因此只需鏈接到C ++源代碼就更容易。

GetHashCode()的默認實現如何工作? 它是否有效且足夠好地處理結構,類,數組等等?

我試圖決定在什麼情況下我應該自己打包,在哪些情況下我可以安全地依靠默認實施來做好。 如果可能的話,我不想重新發明輪子。




ObjectGetHashCode方法的文檔說: “此方法的默認實現不能用作散列目的的唯一對象標識符。”ValueType那個表示“如果調用派生類型的GetHashCode方法,則返回值不太可能適合用作散列表中的鍵。”

byteshortintlongcharstring這樣的基本數據類型實現了一個很好的GetHashCode方法。 其他一些類和結構(例如Point實現了一個GetHashCode方法,該方法可能適用於您的特定需求,也可能不適合您。 你只需要嘗試一下,看看它是否足夠好。

每個類或結構的文檔可以告訴你它是否覆蓋默認實現。 如果它不覆蓋它,你應該使用你自己的實現。 對於您在需要使用GetHashCode方法時自行創建的任何類或結構,您應該製作自己的實現,使用適當的成員來計算哈希代碼。




Related

.net hash gethashcode