当我使用IEquatable
接口实现我想要比较的对象时:
Equals(object)
如果我已经实现了,为什么必须覆盖方法Equals(T)
?
我实施后可以使用==
和!=
运营商IEquatable
吗?
Ray Booysen.. 52
来自MS Docs的文章IEquatable
:
如果实现了
IEquatable
,你也应该重写的基类的实现Equals(Object)
,并GetHashCode()
让他们的行为与该一致的Equals(T)
方法.如果覆盖Equals(Object)
,则在调用类上的静态Equals(Object, Object)
方法时也会调用重写的实现 .此外,您应该重载op_Equality
和op_Inequality
运算符.这可确保所有相等测试都返回一致的结果.
不,运营商不使用Equals方法.它们必须单独超载才能这样做.
轻微的术语修正 - 你不能*覆盖*操作符,但你可以*重载*它们. (13认同)
不,为此目的使用ReferenceEquals().等号运算符(==)通常意味着相同,但可以覆盖(例如对于字符串等). (8认同)
是的,您可以重载==和!= in并将它们与IEquatable接口结合使用.但这需要手动完成,IEquatable不会自动完成.答案的第2部分中的"否"实际上是不正确的.注意:尝试编辑答案,但显然有些人认为评分最高的答案不正确并不足以批准更正编辑. (2认同)
Jon Skeet.. 43
1)正如Ray所说,覆盖Equals(object)
以确保从不知道(静态)实现的类调用方法时的一致性IEquatable
.例如,非泛型集合类将Equals(object)
用于比较.你也应该覆盖GetHashCode()
.
2)实现IEquatable
不会自动重载==和!=运算符,但没有什么可以阻止你这样做,就像System.String
那样.但是,如果你这样做,你应该非常清楚地记录这一点 - 当你在仍然使用身份比较的其他类型的引用(例如MyType和Object)之间进行比较时要小心.我怀疑这样做并不是一个好主意,除非它在你的代码中是一个非常频繁使用的类型,每个人都会非常熟悉它,并且重载的语法糖= =将真正对可读性产生积极影响.
来自MS Docs的文章IEquatable
:
如果实现了
IEquatable
,你也应该重写的基类的实现Equals(Object)
,并GetHashCode()
让他们的行为与该一致的Equals(T)
方法.如果覆盖Equals(Object)
,则在调用类上的静态Equals(Object, Object)
方法时也会调用重写的实现 .此外,您应该重载op_Equality
和op_Inequality
运算符.这可确保所有相等测试都返回一致的结果.
不,运营商不使用Equals方法.它们必须单独超载才能这样做.
1)正如Ray所说,覆盖Equals(object)
以确保从不知道(静态)实现的类调用方法时的一致性IEquatable
.例如,非泛型集合类将Equals(object)
用于比较.你也应该覆盖GetHashCode()
.
2)实现IEquatable
不会自动重载==和!=运算符,但没有什么可以阻止你这样做,就像System.String
那样.但是,如果你这样做,你应该非常清楚地记录这一点 - 当你在仍然使用身份比较的其他类型的引用(例如MyType和Object)之间进行比较时要小心.我怀疑这样做并不是一个好主意,除非它在你的代码中是一个非常频繁使用的类型,每个人都会非常熟悉它,并且重载的语法糖= =将真正对可读性产生积极影响.