C#GetHashCode有两个Int16,也只返回Int32?

ala*_*ere 1 c# int hash int32 gethashcode

抱歉将两个问题合并为一个,它们是相关的.

HashCode对于HashSets等等.据我了解,它们必须是唯一的,而不是更改,并将对象的任何配置表示为单个数字.

我的第一个问题是,我的对象,包含两个Int16s a并且b,它是安全的我GetHashCode回到类似a * n + b,其中n是一个大数,我想也许Math.Pow(2, 16)

同样GetHashCode似乎也特异性地返回Int32类型.

32位可以存储,例如,两个Int16,一个unicode字符或16个N,S,E,W罗盘方向,它并不多,甚至类似于少量节点图的东西可能对它来说太多了.这是否代表C#Hash集合的限制?

Jon*_*eet 7

据我了解,它们必须是独一无二的

不.对于大多数类型而言,它们可能不是唯一的,其可能具有超过2 32个可能的值.理想情况下,如果两个对象具有相同的哈希码,那么它们不太可能相等 - 但您永远不应该假设它们相等的.重要的是,如果他们有不同的哈希码,他们肯定是不平等的.

我的第一个问题是,对于我的对象,包含两个Int16s a和b,我的GetHashCode返回类似于*n + b的东西是安全的,其中n是一个大数字,我想也许Math.Pow(2,16) .

如果它只包含两个Int16值,则最简单的方法是:

return (a << 16) | (ushort) b;
Run Code Online (Sandbox Code Playgroud)

然后该值是唯一的.Hoorah!

GetHashCode似乎以不灵活的方式返回类型Int32.

是.类型如此Dictionary并且HashSet需要能够使用固定大小,以便它们可以使用它来将值放入存储桶中.

32位可以存储,例如,两个Int16,一个unicode字符或16个N,S,E,W罗盘方向,它并不多,甚至类似于少量节点图的东西可能对它来说太多了.这是否代表C#Hash集合的限制?

如果它一个限制,它将是一个.NET限制而不是C#限制 - 但不,它只是对哈希代码所代表的误解.

Eric Lippert有一篇很好的(很明显的)博客文章GetHashCode,你应该阅读它以获取更多信息.

  • @ alan2here:是的.返回常量始终是哈希码的有效策略 - 但是会破坏与哈希表等相关的所有正常效率. (2认同)
  • Jon,正如Hans Passant提醒Marc Gravell对这个问题的评论,@ alan2here*不应该*忽视这个警告.如果他这样做,对于任何负的'b`值,所有`a,b`对都将具有相同的哈希码,而不管a的值如何.如果b小于零,`((a << 16)| b)== b`,因为符号扩展. (2认同)