阅读完这篇文章后我来到了这里,但没有找到相关的答案-因此,在您阅读完整个问题之前,请不要将其标记为重复。
我一直在使用反射器,看着。Object.Equals
我看到的是:
[__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
public virtual bool Equals(object obj)
{
return RuntimeHelpers.Equals(this, obj);
}
而且RuntimeHelpers.Equals
是这样的:
// System.Runtime.CompilerServices.RuntimeHelpers
/// <summary>Determines whether the specified <see cref="T:System.Object" /> instances are considered equal.</summary>
/// <returns>true if the <paramref name="o1" /> parameter is the same instance as the <paramref name="o2" /> parameter, or if both are null, or if o1.Equals(o2) returns true; otherwise, false.</returns>
/// <param name="o1">The first object to compare. </param>
/// <param name="o2">The second object to compare. </param>
[SecuritySafeCritical]
[MethodImpl(MethodImplOptions.InternalCall)]
public new static extern bool Equals(object o1, object o2);
现在,我看不到实现,RuntimeHelpers.Equals
但通过描述,如果两个对象都不是同一实例且不为null,它将object.Equals
再次调用该方法,并且我将陷入循环(我在谈论纯对象))。
当我说纯净的对象时,我的意思是这样的:
object pureObj1 = new object();
object pureObj2 = new object();
bool areEql = pureObj1.Equals(pureObj2);
通过文档,这应该调用Object.Equals
并获得可追溯的stackoverflow。我想也许文档是错误的,并且这检查了基本对象的引用相等性,但是我想确定一下。
底线:
通过Equals
调用比较两个纯对象(例如,不将字符串转换为对象)时,如何确定它们是否相等?-如果不重写Equals
方法而调用Equals
两个对象,会发生什么?
ps有反正我可以看到RuntimeHelpers.Equals
源代码吗?
MSDN上的页面object.Equals(object)
对此进行了详细介绍。具体来说,引用类型的默认实现是引用相等。“继承者注意事项”部分中的表是最直接的。
参考相等;等效于调用Object.ReferenceEquals。
如果MSDN的RuntimeHelpers.Equals(object,object)
Object.Equals(Object)
参数引用不相等且都不为null ,则会调用MSDN的页面。这显然是错误的。实际表现出的行为是RuntimeHelpers.Equals(object,object)
从不打电话Object.Equals(Object)
。
例如,此LINQPad脚本:
void Main()
{
object left = new Foo();
object right = new Foo();
left.Equals(right).Dump();
RuntimeHelpers.Equals( left, right ).Dump();
left = new Bar();
right = new Bar();
left.Equals(right).Dump();
RuntimeHelpers.Equals( left, right ).Dump();
left = new Baz();
right = new Baz();
left.Equals(right).Dump();
RuntimeHelpers.Equals( left, right ).Dump();
left = new Qux();
right = new Qux();
left.Equals(right).Dump();
RuntimeHelpers.Equals( left, right ).Dump();
}
private class Foo {}
private class Bar {
public override bool Equals(object obj) {
"Bar.Equals() called".Dump();
return base.Equals(obj);
}
}
private class Baz {
public override bool Equals(object obj) {
"Baz.Equals() called".Dump();
return RuntimeHelpers.Equals( this, obj );
}
}
private class Qux {
public override bool Equals(object obj) {
"Qux.Equals() called".Dump();
return true;
}
}
在下面显示输出:
错误的
错误的
调用Bar.Equals()
错误的
错误的
Baz.Equals()被称为
错误的
错误的
Qux.Equals()称为
真的
错误的
因此,我从汉斯·帕桑特(Hans Passant)给出的答案中Math.Pow()
有点...恼...
这是\ CLR \ SRC \虚拟机\ ecall.cpp在相关代码SSCLI2.0
FCFuncStart(gObjectFuncs)
FCIntrinsic("GetType", ObjectNative::GetClass, CORINFO_INTRINSIC_Object_GetType)
FCFuncElement("InternalGetHashCode", ObjectNative::GetHashCode)
FCFuncElement("InternalEquals", ObjectNative::Equals)
FCFuncElement("MemberwiseClone", ObjectNative::Clone)
FCFuncEnd()
这是映射到\ 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
我看到了引用比较,空检查,值类型排除,类型匹配检查以及按位相等比较。我不知道怎么Object.Equals(Object)
称呼。我认为该文档RuntimeHelpers.Equals(object,object)
根本不正确。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句