是什么RuntimeHelpers.GetHashCode做(What does RuntimeHe

2019-07-30 03:43发布

所述RuntimeHelpers.GetHashCode(object)方法允许基于对象的标识生成的散列码。 MSDN 指出 :

该RuntimeHelpers.GetHashCode方法总是调用Object.GetHashCode方法非实际上,即使对象的类型已经覆盖了Object.GetHashCode方法。

[MethodImpl(MethodImplOptions.InternalCall)]
[SecuritySafeCritical]
public static extern int GetHashCode(object o);

但是,检查时Object.GetHashCode()使用反射(.NET 4.0)方法中,我们会看到下面的代码:

public virtual int GetHashCode()
{
    return RuntimeHelpers.GetHashCode(this);
}

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

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

Answer 1:

我觉得MSDN文档试图描述的行为 ,而不是实现。 关键点: RuntimeHelpers返回默认实现,你会得到了object.GetHashCode() 覆盖。

如果,例如,你想建立一个参考平等查找这是非常有用的,即使对于已覆盖类型EqualsGetHashCode 。 我这样做的,我保持一个串行,使用RuntimeHelpers.GetHashCode()Object.ReferenceEquals



Answer 2:

问题的关键是, object.GetHashCode()可以重写-而且经常是,如通过string 。 这意味着你不能找出“身份的散列码”的,其默认实现object.GetHashCode()返回。

如果你想实现一个equalty比较器(例如对于这可能是有用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(对象),它是如何工作的实际行为?

观察到的行为是从返回的值RuntimeHelpers.GetHashCode(object)是一样的,其会从非虚拟调用所返回的值Object.GetHashCode() 。 (你不能简单的用C#非虚拟呼叫。)

至于它是如何工作 -这是一个实现细节:)它并不真正的问题出现IMO哪种方式圆形的东西(什么叫什么)。 最重要的是该记录的行为,这是正确的。 无论从一个用户的角度就不会在所有 - 哎呀,不同版本的mscorlib的可能有不同的实现这一点。 如果没有反编译,你不应该能够分辨出来。

这将(IMO)已经远远混乱的Object.GetHashCode已来讲记载RuntimeHelpers.GetHashCode()



Answer 3:

奇怪,当我通过反射看System.Object.GetHashCode我见

public virtual int GetHashCode()
{
    return InternalGetHashCode(this);
}

和runtimehelper:

public static int GetHashCode(object o)
{
    return object.InternalGetHashCode(o);
}

也许这是一个框架的区别? 我期待在2.0组件。



Answer 4:

从你自己的问题,它看起来像RuntimeHelpers.GetHashCode(Object)是真正的非重写的实施Object.GetHashCode()



文章来源: What does RuntimeHelpers.GetHashCode do