GetHashCode()函数仅会在一个地方用到,即为基于散列(hash)的集合定义的散列键时,此类集合包括HashSet和Dictionary<K,V>容器等。
但object基类提供的GetHashCode()实现有很多问题。

  • 对于引用类型,虽然可以正常工作,但效率很低
  • 对于值类型,基类中的实现有时甚至是不正确的

如果我们定义的类型不会在容器中作为键来使用,那就没有什么问题。但如果创建的类型将被当做散列表中的键使用,那么就需要自己实现GetHashCode()。
重载GetHashCode()必须遵循以下规则:

  1. 如果两个对象相对(由operator==定义),那么它们必须生成相同的散列码。否则,这样的散列码将无法用来查找容器中的对象。
  2. 对于任何一个对象A,A.GetHashCode()必须保持不变。不管在A上调用什么方法,A.GetHashCode()都必然总是返回同一个值。这可以确保放在“桶”中的对象总是位于正确的“桶”中。
  3. 对于所有的输入,散列函数应该在所有整数中按照随机分布生成散列码。这样散列容器才能得到足够的效率提升。

Object.GetHashCode()使用System.Object中的一个内部字段来产生序列值。系统创建的每一个对象在创建时都会被指派给一个唯一的对象键(一个整数值)。这些键从1开始,每创建一个任意类型的新对象,键值都会随之增长。对象标识字段会在System.Object构造函数中设置,并且之后不能更改。对于一个指定的对象,Object.GetHashCode()会返回该值作为散列码。

但其实Object.GetHashCode()并不满足第三条规则,一个递增序列在所有整数范围内显然不是一个随机分布。Object.GetHashCode()返回的散列码会集中在整数范围的低端。这就意味着Object.GetHashCode()的实现虽说是正确的,但效率不够好。
System.VauleType覆写GetHashCode()方法,为所有值类型提供了一个默认实现。默认的实现会返回类型中定义的第一个字段散列码。只有当值类型的第一个字段是只读的情况下,VauleType.GetHashCode()才能正常工作。只有当值类型第一个字段包含的值有着相对随机分布时,VauleType.GetHashCode()才会产生一个比较高效的散列码。

最新文章

  1. Memcached和Redis比较
  2. ExtJs动态生成treepanel的Json格式
  3. mamp pro
  4. linux shell ls -1 列显示文件
  5. 【WEB小工具】BaseServlet—一个Servlet处理多个请求
  6. MEF学习小结 z
  7. linux上安装memcached
  8. 插入ts以及判断列是否存在(支持多数据库)
  9. SGU 163.Wise King
  10. (转)android多国语言适配
  11. 当&lt;script&gt;中的type等于text/html的妙用
  12. C-Swipe Mobile 一个适用于Vue2.x的移动端轮播组件
  13. iOS网络编程笔记——GCDAsyncSocket使用
  14. iframe的缺点
  15. springBoot(7)---整合Mybaties增删改查
  16. windows Sever 2012下Oracle 12c安装配置方法图文教程
  17. socket 发送图片
  18. 总结:独立开发 jar 包组件——功能主要是支持查询数据库的所有表数据
  19. onsubmit return false仍提交表单
  20. 【数组】Jump Game

热门文章

  1. Qt webview调用JavaScript 带参函数
  2. Spring开发环境搭建
  3. spring 4.0 JUnit简单的Dao,Service测试
  4. Linux进程KILL不掉的原因
  5. 在虚拟机环境(CentOS7系统)下将kubernetes中部署服务成功,但在虚拟机外部无法访问到服务
  6. jquery抽奖插件+概率计算
  7. 使用 jquery.webcam 进行asp.net 拍照
  8. 序列化 (C#)
  9. centos运行netcore error:package: ‘Microsoft.AspNetCore.Antiforgery‘, version: ‘2.0.3‘
  10. jquery事件之事件委托和事件切换