在项目中,在使用哈希表时。有时会须要Override GetHashCode。

这里给出一种普遍的做法:

版本号1:
实现一个helper。传递类型T。返回这个类型的hashcode。函数逻辑非常直接,仅仅是做了null check而已。假设obj不为空,则直接使用obj的hash code。

public class HashHelper
{
private int _seed = 17;
public int Hash<T>(T obj)
{
// why 31? // https://computinglife.wordpress.com/2008/11/20/why-do-hash-functions-use-prime-numbers/
// shortly, to reduce the conflict of hashing key's distrabution
return 31 * _seed + ((obj == null) ? -1 : obj.GetHashCode());
}
}

为什么使用了magic number 31? 使用素数乘积能够相对添加唯一性,降低哈希键值分配时的冲突;而31则是为了编译器优化的考虑(有效的转换为i<<5-1)。大概搜了一下,这样的实现方式来自JAVA中string 的hash code函数。这里有具体介绍:
https://computinglife.wordpress.com/2008/11/20/why-do-hash-functions-use-prime-numbers/

实现版本号2:
能够扩展这个类成为流畅接口,它能够hash各种类型的。对于值类型来说,重载的意义在于降低装箱。对于集合或泛型,则为了让外部调用更自然。可读性更强。

public class HashFluent
{
private int _seed = 17;
private int _hashContext; public HashFluent Hash<T>(T obj)
{
// why 31?
// https://computinglife.wordpress.com/2008/11/20/why-do-hash-functions-use-prime-numbers/
// shortly, to reduce the conflict of hashing key's distrabution
_hashContext = 31 * _seed + ((obj == null) ? -1 : obj.GetHashCode());
return this;
} public HashFluent Hash(int? value)
{
_hashContext = 31 * _seed + ((value == null) ? -1 : value.GetHashCode());
return this;
} public HashFluent Hash(IEnumerable sequence)
{
if (sequence == null)
{
_hashContext = 31 * _hashContext + -1;
}
else
{
foreach (var element in sequence)
{
_hashContext = 31 * _hashContext + ((element == null) ? -1 : element.GetHashCode());
}
}
return this;
} public override int GetHashCode (){
return _hashContext;
} // add more overridings here ..
// add value types overridings to avoid boxing which is important
}

C# GetHashCode 的实现方式的更多相关文章

  1. WebApi服务Uri加密及验证的两种方式

    最近的一个项目要求服务端与UI层分离,业务层以WebApi方式向外提供所有业务服务,服务在数据保密性方面提出了要求,主要包括: 1:客户端认证: 2:服务请求超时(默认5分钟): 3:服务Get请求的 ...

  2. WPF中的DependencyProperty存储方式详解

    前言 接触WPF有一段时间了,之前虽然也经常使用,但是对于DependencyProperty一直处于一知半解的状态.今天花了整整一下午将这个概念梳理了一下,自觉对这个概念有了较为清晰的认识,之前很多 ...

  3. ASP.net 中关于Session的存储信息及其它方式存储信息的讨论与总结

    通过学习和实践笔者总结一下Session 的存储方式.虽然里面的理论众所周知,但是我还是想记录并整理一下.作为备忘录吧.除了ASP.net通过Web.config配置的方式,还有通过其它方式来存储的方 ...

  4. DotNet加密方式解析--非对称加密

    新年新气象,也希望新年可以挣大钱.不管今年年底会不会跟去年一样,满怀抱负却又壮志未酬.(不过没事,我已为各位卜上一卦,卦象显示各位都能挣钱...).已经上班两天了,公司大部分人还在休假,而我早已上班, ...

  5. C#语法——await与async的正确打开方式

    C#5.0推出了新语法,await与async,但相信大家还是很少使用它们.关于await与async有很多文章讲解,但有没有这样一种感觉,你看完后,总感觉这东西很不错,但用的时候,总是想不起来,或者 ...

  6. C#取出重复的方式以及用字典存储以键存储集合的方法

    最近在做项目的时候,发现有些需求需要特别的方式来实现.下面看代码 private List<string> firstType = new List<string>(); pr ...

  7. C#语法——泛型的多种应用 C#语法——await与async的正确打开方式 C#线程安全使用(五) C#语法——元组类型 好好耕耘 redis和memcached的区别

    C#语法——泛型的多种应用   本篇文章主要介绍泛型的应用. 泛型是.NET Framework 2.0 版类库就已经提供的语法,主要用于提高代码的可重用性.类型安全性和效率. 泛型的定义 下面定义了 ...

  8. [翻译] C# 8.0 新特性 Redis基本使用及百亿数据量中的使用技巧分享(附视频地址及观看指南) 【由浅至深】redis 实现发布订阅的几种方式 .NET Core开发者的福音之玩转Redis的又一傻瓜式神器推荐

    [翻译] C# 8.0 新特性 2018-11-13 17:04 by Rwing, 1179 阅读, 24 评论, 收藏, 编辑 原文: Building C# 8.0[译注:原文主标题如此,但内容 ...

  9. 生成二维码 加密解密类 TABLE转换成实体、TABLE转换成实体集合(可转换成对象和值类型) COOKIE帮助类 数据类型转换 截取字符串 根据IP获取地点 生成随机字符 UNIX时间转换为DATETIME\DATETIME转换为UNIXTIME 是否包含中文 生成秘钥方式之一 计算某一年 某一周 的起始时间和结束时间

    生成二维码 /// <summary>/// 生成二维码/// </summary>public static class QRcodeUtils{private static ...

随机推荐

  1. TransactionProxyFactoryBean 配置问题

    <?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.spr ...

  2. Vue列表渲染,改变数据视图层监测不到的问题

    由于 JavaScript 的限制, Vue 不能检测以下变动的数组: 当你利用索引直接设置一个项时,例如: vm.items[indexOfItem] = newValue 当你修改数组的长度时,例 ...

  3. 利用node搭建本地服务器调试代码

    在命令符中输入 npm install -g live-server安装live-server 安装完成后在项目文件夹下打开cmd,输入live-server启动

  4. xsy 1836 - Shop

    from NOIP2016模拟题36 Description 商店里有n种背包和m种物品,物品体积为1到m,背包容积<=m 给出n个背包的容积 现在要求出这样一个物品集合,满足: 1)对于任意一 ...

  5. hdu 4939 2014 Multi-University Training Contest 7 1005

    Stupid Tower Defense Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/ ...

  6. uniSWF使用注意事项

    美术方面,也就是使用FLASH这里的用户,请注意以下几点, 1.把相同的图案做成元件: 2.凡是补间产生的动画物体,也要做成元件: 以上便可以节省大量的空间,因为当迩把图案做成元件的话,UNISWF导 ...

  7. Yii查看(输出)当前页面执行的sql语句

    在Yii框架下查看当前页面执行的所有sql语句的方法,主要是通过配置相关文件来达到调试sql的目的,具体方法如下: (1)修改 index.php 开启调试模式 在 index.php 文件内增加如下 ...

  8. js 路径改变时获取url参数

    当我们在使用react或vue的router作路由跳转时,为了保持菜单与地址栏状态一致,我们可以使用window.onhashchange捕获#后面的变化 window.onhashchange = ...

  9. 51nod 1092 回文字符串【LCS】

    1092 回文字符串 基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题 收藏 关注 回文串是指aba.abba.cccbccc.aaaa这种左右对称的字符串.每个字符 ...

  10. gitlab升级、汉化、修改root密码

    1.gitlab升级 # 查看当前版本 head -1 /opt/gitlab/version-manifest.txt gitlab-ce 8.9.5 grep "^external_ur ...