您需要生成自己的唯一 ID
如果您的对象具有自然键,则有时可以从对象属性中派生唯一 ID。
如果对象没有自然键,则必须生成唯一 ID,您通常会将唯一 ID 传递给构造函数中的对象。
GetHashCode 是较差的唯一 ID,因为它不能保证是唯一的。
在内部,.NET 不使用 GetHashCode 来实现唯一性。
.NET 在内部使用 GetHashCode 来加速相等比较和 HashBuckets。
如果要生成自己的唯一 ID,则应覆盖 GetHashCode 和 Equals。
这样,.NET 可以使用您的唯一标识符进行相等比较。
.NET GetHashCode() 不需要也不保证是唯一的。
.NET GetHashCode() 不仅限于 Int32。
.NET GetHashCode() 是 Int32。
如果 GetHashCode 不相等,则两个对象不相等。
如果 GetHashCode 相等,则两个对象可能相等也可能不相等。Equals 是决胜局。
对于速度,首先比较 GetHashCode。GetHashCode 也用于 hashbuckets,以提高 HashSet 和 Dictionary 等集合的速度。
如果哈希是唯一的,那么它被认为是完美的哈希。
经典例子
class Point: object
{
protected int x, y;
public Point(int xValue, int yValue)
{
x = xValue;
y = yValue;
}
public override bool Equals(Object obj)
{
// Check for null values and compare run-time types.
if (obj == null || GetType() != obj.GetType())
return false;
Point p = (Point)obj;
return (x == p.x) && (y == p.y);
}
public override int GetHashCode()
{
return x ^ y;
}
}
由于 Point 具有 Int32 X Int32 可能值,因此显然它不能用单个 Int32 唯一标识。GetHashCode 仍然是有价值的并且是必需的。只有 1/Int32 的机会需要更昂贵的 Equals,并且 GetHashCode 用于哈希桶。
考虑简单点
class Point: object
{
protected byte x, y;
public Point(byte xValue, byte yValue)
{
x = xValue;
y = yValue;
}
public override bool Equals(Object obj)
{
// Check for null values and compare run-time types.
if (obj == null || GetType() != obj.GetType())
return false;
Point p = (Point)obj;
return (x == p.x) && (y == p.y);
}
public override int GetHashCode()
{
return (x * 256) + y;
}
}
在这个简单点中,GetHashCode 将唯一标识对象。您不能覆盖其中之一。必须不覆盖或覆盖两者。