The MSDN documentation on Object.GetHashCode() describes 3 contradicting rules for how the method should work.
Rules 1 & 3 aren't really a contradiction.
For a reference type the hash code is derived from a reference to the object - change an object's property and the reference is the same.
For value types the hash code is derived from the value, change a property of a value type and you get a completely new instance of the value type.