While disassembling the .Net Source Code using Reflector, I came upon the Equals implementation in the Object Class and it refers to
bool InternalEquals(obj
First, find in sscli20\clr\src\vm\ecall.cpp function mapping ("InternalEquals" -> ObjectNative::Equals):
FCFuncStart(gObjectFuncs)
FCIntrinsic("GetType", ObjectNative::GetClass, CORINFO_INTRINSIC_Object_GetType)
FCFuncElement("InternalGetHashCode", ObjectNative::GetHashCode)
FCFuncElement("InternalEquals", ObjectNative::Equals)
FCFuncElement("MemberwiseClone", ObjectNative::Clone)
FCFuncEnd()
Next, find an implementation ObjectNative::Equals (published by Mehrdad Afshari)
It's declared as [MethodImpl(MethodImplOptions.InternalCall)]
. It means that it's implemented in the CLR itself, as a native procedure, not a .NET assembly.
You can view a similar CLR source code by looking at Microsoft SSCLI (aka Rotor).
In SSCLI 2.0 it's implemented as (in sscli20/clr/src/vm/comobject.cpp
):
FCIMPL2(FC_BOOL_RET, ObjectNative::Equals, Object *pThisRef, Object *pCompareRef)
{
CONTRACTL
{
THROWS;
DISABLED(GC_NOTRIGGER);
INJECT_FAULT(FCThrow(kOutOfMemoryException););
MODE_COOPERATIVE;
SO_TOLERANT;
}
CONTRACTL_END;
if (pThisRef == pCompareRef)
FC_RETURN_BOOL(TRUE);
// Since we are in FCALL, we must handle NULL specially.
if (pThisRef == NULL || pCompareRef == NULL)
FC_RETURN_BOOL(FALSE);
MethodTable *pThisMT = pThisRef->GetMethodTable();
// If it's not a value class, don't compare by value
if (!pThisMT->IsValueClass())
FC_RETURN_BOOL(FALSE);
// Make sure they are the same type.
if (pThisMT != pCompareRef->GetMethodTable())
FC_RETURN_BOOL(FALSE);
// Compare the contents (size - vtable - sink block index).
BOOL ret = memcmp(
(void *) (pThisRef+1),
(void *) (pCompareRef+1),
pThisRef->GetMethodTable()->GetBaseSize() - sizeof(Object) - sizeof(int)) == 0;
FC_GC_POLL_RET();
FC_RETURN_BOOL(ret);
}
FCIMPLEND