You will need to generate you own unique ID
Some times can derive a unique ID from object properties if your object has a natural key.
If the object does not have a natural key then must generate a unique ID and you would typically pass the unique ID to the object in the constructor.
GetHashCode is poor unique ID as it is not guaranteed to be unique.
Internally .NET does not use GetHashCode for uniqueness.
Internally .NET uses GetHashCode to speed equality comparison and for HashBuckets.
If you are going to generate your own unique ID then you should override GetHashCode and Equals.
That way .NET can use your unique identifier for equality comparison.
.NET GetHashCode() is not required nor guaranteed to be unique.
.NET GetHashCode() is not just limited to Int32.
.NET GetHashCode() is Int32.
If the GetHashCode are not equal then two objects are not equal.
If GetHashCode is equal then two objects may or may not be equal.
Equals is the tie breaker.
For speed first GetHashCode is compared.
GetHashCode is also use for hashbuckets for speed of collections like HashSet and Dictionary.
If a hash is unique then it is considered a perfect hash.
Classic example
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;
}
}
Since Point has Int32 X Int32 possible values then obviously it cannot be uniquely identified with a single Int32.
Still GetHashCode is of value and required. There is only 1/Int32 chance the more expensive Equals will be required and the GetHashCode is used for hash buckets.
Consider simple point
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;
}
}
In this simple point GetHashCode will uniquely identify the object.
You cannot override one of the other. Must override neither or both.