Dan*_*ker 7 c# equality equals
在通过C#第4版(微软出版社)阅读Jeffrey Richter的CLR时,作者曾指出,虽然Object.Equals目前检查身份相同,但Microsoft 应该实现如下方法:
public class Object {
public virtual Boolean Equals(Object obj) {
// The given object to compare to can't be null
if (obj == null) return false;
// If objects are different types, they can't be equal.
if (this.GetType() != obj.GetType()) return false;
// If objects are same type, return true if all of their fields match
// Because System.Object defines no fields, the fields match
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
这让我很奇怪:默认情况下,相同类型的每个非null对象都是相同的?因此,除非被覆盖:类型的所有实例都相等(例如,所有锁定对象都相等),并返回相同的哈希码.并且假设==on Object仍然检查引用相等,这将意味着(a == b) != a.Equals(b)哪个也是奇怪的.
我认为事物是平等的,如果它是完全相同的(身份)是一个更好的想法,而不仅仅是让一切都平等,除非被覆盖.但这是微软出版的一本着名的第四版,所以这个想法必定有一些优点.我阅读了文本的其余部分,但不禁怀疑:为什么作者会这样做呢?我在这里错过了什么?Richter的实现优于当前的Object.Equals实现的巨大优势是什么?
当前默认值Equals()执行所谓的浅比较(或参考比较),然后如果引用不同则不再检查.
我认为这对于基础实现是完全可以接受的.我当然不会认为这是错误的或不完整的.
您引用的Richter的示例1 对于基本System.Object也是完全合法的.他的实现的问题是它可以说应该被声明为抽象2 - Equals()如果你没有覆盖它,那么你的方法最终会导致派生对象不可靠(因为Equals()它应该进行深度比较).必须在所有派生对象上覆盖此方法将会有很多工作,因此Microsoft方法作为默认方式更好.所以在本质上你是正确的:里希特的例子很奇怪 - 最好默认为不相等而不是反过来(true如果人们忘记覆盖它,则默认会导致一些相当有趣的行为).
(仅供参考,这是本书中公布的默认实现)

1:里希特是一个聪明的人,他知道他的东西,我一般不会与他说的任何事情争论.你必须明白,MS工程师必须长时间地思考很多事情,因为他们知道他们没有灵活性能够弄错,然后才能解决问题.无论他们多么正确,人们总会在以后再次猜测它们,并提供其他意见.这并不意味着原始错误或替代方案是错误的 - 它只是意味着有另一种选择.
2:当然这意味着没有基本实现,这很好,因为它本身是不可靠的.