所述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)
,它是如何工作的? 它是如何计算哈希?
我觉得MSDN文档试图描述的行为 ,而不是实现。 关键点: RuntimeHelpers
返回默认实现,你会得到了object.GetHashCode()
不覆盖。
如果,例如,你想建立一个参考平等查找这是非常有用的,即使对于已覆盖类型Equals
和GetHashCode
。 我这样做的,我保持一个串行,使用RuntimeHelpers.GetHashCode()
和Object.ReferenceEquals
。
问题的关键是, 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()
奇怪,当我通过反射看System.Object.GetHashCode我见
public virtual int GetHashCode()
{
return InternalGetHashCode(this);
}
和runtimehelper:
public static int GetHashCode(object o)
{
return object.InternalGetHashCode(o);
}
也许这是一个框架的区别? 我期待在2.0组件。
从你自己的问题,它看起来像RuntimeHelpers.GetHashCode(Object)
是真正的非重写的实施Object.GetHashCode()