独自のIDを生成する必要があります
オブジェクトに自然キーがある場合、オブジェクトのプロパティから一意のIDを取得できる場合があります。
オブジェクトに自然キーがない場合は、一意のIDを生成する必要があり、通常、コンストラクターでオブジェクトに一意のIDを渡します。
GetHashCodeは、一意であることが保証されていないため、一意のIDとしては不十分です。
内部的には、.NETは一意性のためにGetHashCodeを使用しません。
内部的には、.NETはGetHashCodeを使用して、同等性の比較とHashBucketsを高速化します。
独自の一意のIDを生成する場合は、GetHashCodeとEqualsをオーバーライドする必要があります。
そうすれば、.NETは一意の識別子を使用して同等性を比較できます。
.NET GetHashCode()は必須ではなく、一意であることが保証されていません。
.NET GetHashCode()は、Int32だけに限定されません。
.NET GetHashCode()はInt32です。
GetHashCodeが等しくない場合、2つのオブジェクトは等しくありません。
GetHashCodeが等しい場合、2つのオブジェクトは等しい場合と等しくない場合があります。Equalsはタイブレーカーです。
速度については、最初にGetHashCodeが比較されます。GetHashCodeは、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にはInt32XInt32の可能な値があるため、単一のInt32で一意に識別できないことは明らかです。それでもGetHashCodeは価値があり、必須です。より高価なEqualsが必要になる可能性は1/Int32のみであり、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はオブジェクトを一意に識別します。他のいずれかをオーバーライドすることはできません。どちらも、または両方をオーバーライドする必要があります。