我对不可变类型的HashCode有一些疑问。
这是一个示例类:
public class Id {
private readonly object _value;
private readonly int _hash = -1;
public Id( object value ) {
_value = value;
_hash = ( int ) ( 7 * value.GetType().GetHashCode() + 7 + 7 * _value.GetHashCode() );
}
public object Value {
get {
return _value;
}
}
public override int GetHashCode() {
return _hash;
}
public override bool Equals( object obj ) {
Id other = obj as Id;
if ( other == null ) {
return false;
}
return this.GetHashCode() == other.GetHashCode();
}
}
答案 0 :(得分:8)
您可以预生成哈希码,但为什么?只需在需要时生成它(在GetHashCode
中),然后可以存储它 - 大多数对象永远不需要有一个哈希,所以它只会减慢程序。
当调用方法GetHashCode()时,我是否应该再次生成Hashcode? p>
不可变对象的哈希码应始终相同,因此无论是再次生成还是存储它都不会产生任何影响,除非存储会提高性能。
注意:您不能通过比较HashCodes来定义Equals
- 两个不同的对象可能具有相等的HashCodes(hash collsion)。
答案 1 :(得分:3)
这实际上取决于用例。
你经常使用哈希吗?然后预生成它,因为对象是不可变的,每次计算它都是不必要的,因为结果总是相同的。
是不是哈希使用了很多?然后不要预生成它,因为它会不必要地减慢程序,计算可能不会使用的哈希。
第三个(也是最好的,在我看来)选项是计算GetHashCode中的散列并缓存结果,仅计算一次散列并在此后每次返回此缓存散列。这样,在从未使用过时,没有时间计算哈希值,也不会在每次调用GetHashCode时不必要地计算哈希值。虽然这确实意味着内存用于在对象中存储哈希。
答案 2 :(得分:1)
不要预生成的原因:它减慢了对象的创建速度。
始终重新生成的原因:您保存了保留哈希码所需的存储空间。
为了记录,我可能会预先计算哈希码并将其存储为不可变对象,除非分析显示它很昂贵并且我不经常访问该值。