为什么以下文档在实现方法时会谈论不同的Equals
方法?
第二个文档(更新的)没有显式实现Equals
(like public bool Equals(MySuperTrooperClass o)
) 的强类型版本。
从其中一个准则中删除强类型方法的根本原因是什么?我应该在生产代码中使用哪种方法?
为什么以下文档在实现方法时会谈论不同的Equals
方法?
第二个文档(更新的)没有显式实现Equals
(like public bool Equals(MySuperTrooperClass o)
) 的强类型版本。
从其中一个准则中删除强类型方法的根本原因是什么?我应该在生产代码中使用哪种方法?
删除强类型版本没有任何好处。恰恰相反,正如第一页本身所提到的
还建议除了实现 Equals(对象)之外,任何类也为自己的类型实现 Equals(类型),以提高性能。
这对于值类型来说是双重的。
我假设第二页根本不关心这个,因为只有弱类型的版本被定义在System.Object
. 强类型版本通常与实现密切相关IEquatable<T>
,其文档中提到了 和 之间的Equals(T)
交互Equals(object)
。
Microsoft 决定在许多原始类型中重载的一个不幸的副作用Equals
是,在许多情况下,由于隐式转换,即使((Object)X).Equals(Y)
将表现为等价关系(它应该如此),X.Equals(Y)
也不会。例如,3.Equals(3.0)
将返回 false,但(3.0).Equals(3)
将返回 true。虽然==
运算符没有那么糟糕(通常是 if X==Y
, Y==X
),但它仍然没有指定等价关系(例如,如果 X = Int64.MaxValue、Y=X-1 和 Z=(Double)X,则 X== Z 和 Y==Z 但 X!=Y)。
微软放弃关于提供与Equals()
行为相同的重载的建议的原因Equals(Object)
可能是,虽然隐式强制转换可能会使前者无法表现为等价关系,但后者应该表现为等价关系,没有例外。
您应该实现强类型的 Equals 以提高性能。正如第一篇文章中所写
当你想检查两个事物是否具有相同的值时,你使用 ==
当你想检查两个事物是否真的引用同一个实例时,你使用 Equals()。
请记住,只有当 Equals() 为真时,== 也必须为真。
关于 GetHashCode() - 在某些情况下包含结构(如 Dictionary)使用此特定方法来区分数据。由您决定如何区分您的数据,但 GetHashCode() 在更改对象的值以使其正常工作时不得更改。这意味着它应该在对象生命周期内保持相同的值。
当你做这样的事情时:
MyClass A = new MyClass();
MyClass B = A;
当您检查 if (A==B) 时,您实际上检查的是指针 A 地址是否与指针 B 地址具有相同的值。
所以,在 99.99% 的共同开发中,你不需要实现 Equals()。