关键是object.GetHashCode()
可以覆盖 - 并且经常是,例如通过string
. 这意味着您无法找到默认实现object.GetHashCode()
返回的“身份哈希码”。
如果您想实现一个只考虑对象身份的相等比较器(例如,对于 a HashSet
),这可能很有用。
例如:
public class IdentityComparer<T> : IEqualityComparer<T> where T : class
{
public bool Equals(T x, T y)
{
// Just for clarity...
return object.ReferenceEquals(x, y);
}
public int GetHashCode(T x)
{
// The nullity check may be unnecessary due to a similar check in
// RuntimeHelpers.GetHashCode, but it's not documented
return x == null ? 0 : RuntimeHelpers.GetHashCode(x);
}
}
然后:
string x = "hello";
string y = new StringBuilder("h").Append("ello").ToString();
Console.WriteLine(x == y); // True (overloaded ==)
Console.WriteLine(x.GetHashCode() == y.GetHashCode()); // True (overridden)
IdentityComparer<string> comparer = new IdentityComparer<string>();
Console.WriteLine(comparer.Equals(x, y)); // False - not identity
// Very probably false; not absolutely guaranteed (as ever, collisions
// are possible)
Console.WriteLine(comparer.GetHashCode(x) == comparer.GetHashCode(y));
编辑:只是为了澄清一点......
那么 RuntimeHelpers.GetHashCode(object) 的实际行为是什么,它是如何工作的?
观察到的行为是从返回RuntimeHelpers.GetHashCode(object)
的值与从非虚拟调用返回的值相同Object.GetHashCode()
。(你不能轻易地用 C# 编写那个非虚拟调用。)
至于它是如何工作的 - 这是一个实现细节:) IMO 以哪种方式发生事情并不重要(什么叫什么)。重要的是记录在案的行为,这是正确的。哎呀,不同版本的 mscorlib 可以以不同的方式实现这一点——从用户的角度来看,这根本不重要。如果没有反编译,您应该无法区分。
如果Object.GetHashCode
以RuntimeHelpers.GetHashCode()
.