设A是一个类,其中一些成员为x,y,z:
Class A {
int x;
int y;
String z;
...
}
A是一个Object,因此它继承了Object中定义的“Equals”函数。 这个函数的默认行为是什么?它是检查成员是否相等还是检查引用相等性?
答案 0 :(得分:49)
Equals的默认实现 支持引用相等 引用类型和按位相等 对于值类型。参考平等 表示对象引用 比较指的是同一个对象。 按位相等意味着对象 被比较的具有相同的二进制 表示。
答案 1 :(得分:6)
答案 2 :(得分:0)
对于“我想确切地知道它是如何工作的”,以下人员是源代码参考。我不确定第一个代码片段中的注释中描述的“加载器技巧”如何与以下事实有关:在C ++代码中,也使用相同的方法处理ValueType。
https://source.dot.net/#System.Private.CoreLib/Object.cs,50
// Returns a boolean indicating if the passed in object obj is
// Equal to this. Equality is defined as object equality for reference
// types and bitwise equality for value types using a loader trick to
// replace Equals with EqualsValue for value types).
public virtual bool Equals(object? obj)
{
return RuntimeHelpers.Equals(this, obj);
}
[MethodImpl(MethodImplOptions.InternalCall)]
public static extern new bool Equals(object? o1, object? o2);
FCIMPL2(FC_BOOL_RET, ObjectNative::Equals, Object *pThisRef, Object *pCompareRef)
{
CONTRACTL
{
FCALL_CHECK;
INJECT_FAULT(FCThrow(kOutOfMemoryException););
}
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->IsValueType())
FC_RETURN_BOOL(FALSE);
// Make sure they are the same type.
if (pThisMT != pCompareRef->GetMethodTable())
FC_RETURN_BOOL(FALSE);
// Compare the contents (size - vtable - sync block index).
DWORD dwBaseSize = pThisRef->GetMethodTable()->GetBaseSize();
if(pThisRef->GetMethodTable() == g_pStringClass)
dwBaseSize -= sizeof(WCHAR);
BOOL ret = memcmp(
(void *) (pThisRef+1),
(void *) (pCompareRef+1),
dwBaseSize - sizeof(Object) - sizeof(int)) == 0;
FC_GC_POLL_RET();
FC_RETURN_BOOL(ret);
}
FCIMPLEND