Effective C#阅读笔记-7GetHashCode陷阱

GetHashCode只有在一种情况下会使用:在基于Hash的集合容器中计算key(键值)时会用到,类似Hashtable和Dictionary。对于默认的System.Object.GetHashCode(). 方法对于引用类型是可以正常工作的的但是效率底下,但是对于值类型通常是有问题的。

GetHashCode() is used in one place only: to define the hash value for keys in a hash-based collection, typically the Hashtable or Dictionary containers.

如果需要为自己的类重写GetHashCode()方法,需要满足一下三个原则:

1. 如果连个对象是相等的(操作符定义operator==),那么两个对象的GetHashCode方法需要返回相同的值,否则将不能在容器中通过hash码取出对象

If two objects are equal (as defined by operator==), they must generate the same hash value. Otherwise, hash codes can't be used to find objects in containers.

2.对于任何一个对象,GetHashCode任何时候返回的值都是一样的,是实例不变的,一个对象只有一个HashCode,无论调用任何方法返回的HashCode都是一样的。

For any object A, A.GetHashCode() must be an instance invariant. No matter what methods are called onA, A.GetHashCode() must always return the same value. That ensures that an object placed in a bucket is always in the right bucket.

3.Hash函数能够针对所有的Inputs生成一个比较好的分布,而不出现碰撞。

The hash function should generate a random distribution among all integers for all inputs. That's how you get efficiency from a hash-based container.

对于引用类型,默认的GetHashCode()原理为,每一个对象创建的时候都为唯一分配一个递增的整数标识符,创建以后这个标识符将不能修改,GetHashCode返回的就是这个值

Object.GetHashCode() uses an internal field in theSystem.Object class to generate the hash value. Each object created is assigned a unique object key, stored as an integer, when it is created. These keys start at1 and increment every time a new object of any type gets created. The object identity field is set in theSystem.Object constructor and cannot be modified later. Object.GetHashCode() returns this value as the hash code for a given object.

对于值类型,System.ValueType 重写了GetHashCode()方法,返回类型定义里面第一个字段的hashcode。因此对于自定义的值类型,如果要作为hash容器的key,需要自定义GetHashCode()函数,保证能够满足上面的三个原则。

public struct MyStruct
 {
  private string   _msg;
  private int      _id;
  private DateTime _epoch;
}

如上面所示:MyStruct对象返回的hashcode,为_msg字段的hashcode.下面的语句将会一直返回为true

MyStruct s = new MyStruct( );
return s.GetHashCode( ) == s._msg.GetHashCode( );

GetHashCode() has very specific requirements: Equal objects must produce equal hash codes, and hash codes must be object invariants and must produce an even distribution to be efficient. All three can be satisfied only for immutable types. For other types, rely on the default behavior, but understand the pitfalls.



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值