【发布时间】:2014-11-28 20:53:22
【问题描述】:
我正在阅读Effective C#,有一条关于Object.GetHashCode()的评论我不明白:
Object.GetHashCode()使用System.Object类中的内部字段来生成哈希值。创建的每个对象都被分配一个唯一的对象键,在创建时存储为整数。
这些键从 1 开始,每次获得任何类型的新对象时递增 创建的。对象标识字段在System.Object构造函数中设置,以后无法修改。Object.GetHashCode()将此值作为给定对象的哈希码返回。
我试图查看Object.GetHashCode() 的文档,但没有找到任何相关信息。
我写了一段简单的代码来打印新生成对象的哈希码:
using System;
namespace TestGetHashCode
{
class Program
{
static void Main(string[] args)
{
for (int i = 0; i < 100; i++)
{
object o = new object();
Console.WriteLine(o.GetHashCode());
}
}
}
}
打印的前几个数字是:
37121646,
45592480,
57352375,
2637164,
41014879,
3888474,
25209742,
26966483,
31884011
这似乎不适合
这些键从 1 开始,并在每次创建任何类型的新对象时递增...
Object.GetHashCode()返回此值
然后,为了在System.Object 中找到这个“内部字段”,我尝试使用ReSharper decompiled sources,但我找到的代码是
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
[__DynamicallyInvokable]
public virtual int GetHashCode()
{
return RuntimeHelpers.GetHashCode(this);
}
再次使用反编译的源代码,我发现RuntimeHelpers.GetHashCode 被实现为
[SecuritySafeCritical]
[__DynamicallyInvokable]
[MethodImpl(MethodImplOptions.InternalCall)]
public static int GetHashCode(object o);
在the MethodImpl attribute 之后,我似乎无法查看实现,这对我来说是一条死胡同。
有人可以解释作者的评论(第一句话)吗?
Object 类中的内部字段是什么以及它如何用于实现Object.GetHashCode()?
【问题讨论】:
-
@Yuval Itzchakov:讽刺吗?否则,你为什么这么认为?
-
@Yuval Itzchakov:为什么你认为
GetHashCode()必须返回一个唯一标识符?它被称为Get*Hash*Code()而不是Get*UniqueIdentifier*()有目的 -
@Yuval Itzchakov:“将为所有返回的对象生成相等性”——这是不正确的。如果它们的哈希码匹配,则永远不应该平等对待对象。实际上恰恰相反:相等的对象必须返回相等的哈希码,但相等的哈希码并不意味着对象相等。 msdn.microsoft.com/en-us/library/… "你不应该假设相等的哈希码意味着对象相等。"
-
@Yuval Itzchakov:“谁只看哈希码相等”——没有人应该这样做。如果有人做了一些愚蠢的事情——这不是鼓励他们继续这样做的理由。 .net 并非如此。如果是第 3 方库的情况,则必须将其报告为错误并进行修复。
标签: c# object gethashcode