RuntimeHelpers.GetHashCode做了什么

Ste*_*ven 21 .net c# clr base-class-library

RuntimeHelpers.GetHashCode(object)方法允许基于对象的身份生成哈希码.MSDN 声明:

RuntimeHelpers.GetHashCode方法始终非虚拟地调用Object.GetHashCode方法,即使对象的类型已重写Object.GetHashCode方法.

[MethodImpl(MethodImplOptions.InternalCall)]
[SecuritySafeCritical]
public static extern int GetHashCode(object o);
Run Code Online (Sandbox Code Playgroud)

但是,在Object.GetHashCode()使用Reflector(.NET 4.0)检查方法时,我们将看到以下代码:

public virtual int GetHashCode()
{
    return RuntimeHelpers.GetHashCode(this);
}
Run Code Online (Sandbox Code Playgroud)

这让我相信MSDN文档是错误的,因为Object.GetHashCode从内部调用RuntimeHelpers.GetHashCode(object)会导致堆栈溢出.

那么它的实际行为是什么RuntimeHelpers.GetHashCode(object)以及它是如何工作的?它是如何计算哈希值的?

Mar*_*ell 23

我认为MSDN文档试图描述行为,而不是实现.关键点:RuntimeHelpers返回未被覆盖的默认实现.object.GetHashCode()

如果,例如,你想建立一个本真的很有参考平等查找,即使对于已覆盖类型EqualsGetHashCode.我在使用RuntimeHelpers.GetHashCode()和维护的序列化程序中执行此操作Object.ReferenceEquals.


Jon*_*eet 11

重点是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);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后:

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));
Run Code Online (Sandbox Code Playgroud)

编辑:只是澄清一下......

那么RuntimeHelpers.GetHashCode(对象)的实际行为是什么?它是如何工作的?

观察到的行为是返回值从RuntimeHelpers.GetHashCode(object)相同这将从非虚拟呼叫被返回的值Object.GetHashCode().(您无法轻松地在C#中编写非虚拟调用.)

至于它是如何工作的 - 这是一个实现细节:) IMO在哪些方面发生事情(什么叫什么)并不重要.重要的是记录的行为,这是正确的.哎呀,不同版本的mscorlib可以以不同的方式实现它 - 从用户的角度来看根本不重要.没有反编译,你不应该分辨出来.

它(IMO)Object.GetHashCode在记录方面会更加令人困惑RuntimeHelpers.GetHashCode().