Equals:值类型比较数值。引用类型比较地址。String是特殊的引用类型,比较数值。(值类型的基类ValueType 重写了Equals方法,实现了内容的比较。)
GetHashCode:获得当前对象的哈希代码。

GetHashCode有什么用

哈希码是一个数字值,用于在基于哈希的集合中插入和标识对象。
GetHashCode可以用于判断相等。GetHashCode方法为需要快速检查对象相等性的算法提供此哈希码。默认不同实例的哈希值是不同的。(可改写)

如果两个对象相等,则它们必须具有相同的哈希码。
如果您有一个类,该类的实例通过引用相等性进行比较(比较引用地址),则无需重写GetHashCode。默认实现保证两个相同引用的对象具有相同的哈希码。 (您在同一个对象上两次调用相同的方法,因此结果是相同的。)
如果编写的类需要实现自己的、与引用相等性不同的相等性,则必须重写GetHashCode,以使两个比较相等的对象具有相等的哈希码。比如,比较文件内容是否相同,则应该改写GetHashCode方法为“计算并比较MD5”。

Tips:

If you override the GetHashCode method, you should also override Equals, and vice versa. If your overridden Equals method returns true when two objects are tested for equality, your overridden GetHashCode method must return the same value for the two objects.

Equals方法和GetHashCode方法的重写应该同时存在。如果Equals方法返回的结果是true,那么GetHashCode方法返回的结果应该相同。如果GetHashCode方法返回的结果相同,那么Equals方法返回的结果不一定是true。
.NET Framework不保证GetHashCode方法的默认实现,并且此方法返回的值在.NET Framework版本和平台(例如32位和64位平台)之间可能有所不同。
哈希码不是永久值,因此请勿序列化,将哈希值存储在数据库中等。

Object.ReferenceEquals静态方法

Object.ReferenceEquals静态方法比较的是引用地址,是高效调用实例Equals方法

示例代码

UseEqualsAndHashCodesDemo

参考资料

Object.GetHashCode 方法
GetHashCode 要你到底何用
Object.GetHashCode