MSDN says:
“GetHashCode方法的默认实现不保证不同对象的唯一返回值。”
但另一方面,当我使用sn.exe工具时,它确保了一个唯一的哈希值来创建一个强命名的程序集。如果我没有指出错误,那么程序集的所有内容都将转换为哈希值。
那么,为什么GetHashCode()的默认实现不使用sn.exe使用的相同算法来为对象创建唯一的哈希值,并期望开发人员实现它?
答案 0 :(得分:2)
这是完全不同的两件事。
GetHashCode()
函数定义返回(仅)32位整数。它应该使用快速算法,并且(不能)保证唯一性。 PC可以快速生成足够的字符串来显示冲突。
当您对应用程序(文档)进行签名时,您将得到更大的散列(如128或256位)。虽然理论上你可能仍然有碰撞,但这没有实际意义。
答案 1 :(得分:2)
没有足够的比特。 GetHashCode()返回其中的32个,因此永远不会有超过40亿个不同的值。生日悖论大大降低了这一点。 sn.exe(而不是sk.exe)生成的强名称使用SHA1哈希。返回160位,允许2 ^ 160个不同的值。
这是一个真正的大数字(1.4E48),通过绝对数量确保唯一性。有点类似于使用128位的Guid。不一样,Guid生成器确保不会发生重复,SHA1没有这样的保证。
GetHashCode的位数有限,因为该方法的主要要求是 fast 。除了为散列集合提供存储桶索引之外,它的用途是快速进行相等测试。 GetHashCode需要比Equals(),给予或接受快一个数量级,以使其有用。这需要削减许多角落,通常,包含引用类型的结构的GetHashCode实现仅返回第一个成员的GetHashCode值。
答案 2 :(得分:1)
程序可以创建的对象数量没有限制,可以调用GetHashCode()
,然后放弃。但是,GetHashCode()
可以返回4,294,967,296个不同值的限制。如果一个程序恰好调用GetHashCode
4,294,967,297次,那么这些调用中至少有一个必须返回之前已经返回的值。
理论上,系统可以保留一个哈希代码值池,以及被放弃的对象将其哈希码放回池中,以便GetHashCode()
可以保证它永远不会返回与任何其他 live 对象相同的值(假设至少有不超过4,294,967,296个活动对象)。另一方面,保留这些信息将是昂贵的,并没有真正提供太多的好处。从实际角度来看,系统在构造对象或第一次调用GetHashCode()
时生成任意数字也同样出色。偶尔会发生碰撞,但通常不足以打扰编写良好的代码。
答案 3 :(得分:0)
无关。不知道你怎么能把这两个联系起来!!
仍然要添加更多参数:
值的“哈希码”不能保证不同值的唯一性。但它确实'保证'给定值/对象的相同哈希码!这意味着:
var hashOne = "SO".GetHashCode();
var hastTwo = "SO".GetHashCode();
Debug.Assert(hashOne==hashTwo); //The assertion would succeed.
SN只是生成一个随机唯一编号,在实例上没有逻辑。