这是我自制的建筑工人。
用法:
hash = new HashCodeBuilder().
Add(a).
Add(b).
Add(c).
Add(d).
GetHashCode();
Run Code Online (Sandbox Code Playgroud)
不要紧,什么类型的字段a,b,c和d是,易于扩展,无需创建阵列。
资源:
public sealed class HashCodeBuilder
{
private int hash = 17;
public HashCodeBuilder Add(int value)
{
unchecked
{
hash = hash * 31 + value; //see Effective Java for reasoning
// can be any prime but hash * 31 can be opimised by VM to hash << 5 - hash
}
return this;
}
public HashCodeBuilder Add(object value)
{
return Add(value != null ? value.GetHashCode() : 0);
}
public HashCodeBuilder Add(float value)
{
return Add(value.GetHashCode());
}
public HashCodeBuilder Add(double value)
{
return Add(value.GetHashCode());
}
public override int GetHashCode()
{
return hash;
}
}
Run Code Online (Sandbox Code Playgroud)
用法示例:
public sealed class Point
{
private readonly int _x;
private readonly int _y;
private readonly int _hash;
public Point(int x, int y)
{
_x = x;
_y = y;
_hash = new HashCodeBuilder().
Add(_x).
Add(_y).
GetHashCode();
}
public int X
{
get { return _x; }
}
public int Y
{
get { return _y; }
}
public override bool Equals(object obj)
{
return Equals(obj as Point);
}
public bool Equals(Point other)
{
if (other == null) return false;
return (other._x == _x) && (other._y == _y);
}
public override int GetHashCode()
{
return _hash;
}
}
Run Code Online (Sandbox Code Playgroud)
我使用以下内容:
public static int ComputeHashFrom(params object[] obj) {
ulong res = 0;
for(uint i=0;i<obj.Length;i++) {
object val = obj[i];
res += val == null ? i : (ulong)val.GetHashCode() * (1 + 2 * i);
}
return (int)(uint)(res ^ (res >> 32));
}
Run Code Online (Sandbox Code Playgroud)
使用这样的助手快速、简单且可靠,但它有两个潜在的缺点(您不太可能经常遇到,但最好注意一下):
int x, ComputeHashFrom(x*-3, x) == 0- 因此,如果您的对象具有某些病态属性,您可能会遇到许多哈希代码冲突,从而导致字典和哈希集性能不佳。这种情况不太可能发生,但类型感知哈希码计算可以更轻松地避免此类问题。params- 如果您只有两个成员要处理,这会带来相当多不必要的开销。这两个缺点都不会导致任何错误,只是效率低下;并且两者都在探查器中显示为此方法或哈希代码使用者的内部中的信号点。
| 归档时间: |
|
| 查看次数: |
2680 次 |
| 最近记录: |