您需要生成自己的唯一 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 将唯一标识对象。
您不能覆盖其中之一。必须不覆盖或覆盖两者。