Understanding IEquatable
当我使用IEquatable接口实现要比较的对象时:
如果我已经实现了Equals(T),为什么要重写Equals(object)方法?
在实现IEquatable之后,我可以使用==和!=操作符吗?
摘自MS Docs关于IEquatable的文章:
If you implement IEquatable, you should also override the
base class implementations of
Equals(Object) and
GetHashCode() so that their behavior is
consistent with that of the
Equals(T)
method. If you do override
Equals(Object), your
overridden implementation is also
called in calls to the static
Equals(Object, Object)
method on your class. In addition,
you should overload the op_Equality
and op_Inequality operators.
This ensures that all tests for equality
return consistent results.
号
不,运算符不使用Equals方法。它们必须单独超载才能这样做。
- 因此,当您处理对象时,is==假定仅表示完全相同的内存地址(相同的实例)
- 差不多。更多信息请访问:msdn.microsoft.com/en-us/library/53k8ybth(vs.80).aspx
- 不,为此使用referenceEquals()。相等运算符(==)通常表示相同,但可以重写(例如字符串等)。
- 感谢保罗·简把这件事弄清楚。
- 轻微的术语更正-您不能重写操作符,但可以重载它们。
- 是的,你可以超载==和!=并与IEquatable接口一起使用。但这需要手动完成,它不会自动与iequatable一起出现。答案第2部分中的"否"实际上是不正确的。注意:尝试编辑答案,但显然有些人认为最高评分的答案不正确,不足以批准更正编辑。
- @亚历克文完成了!这并不是说不应该进行这样的编辑;而是说你希望评审员重新做你自己的研究,来验证你的更改。有时,他们甚至可能不熟悉所讨论的编程语言。
1)正如Ray所说,当从不知道(静态地)实现IEquatable的类调用方法时,重写Equals(object)以确保一致性。例如,非泛型集合类将使用Equals(object)进行比较。您还应该覆盖GetHashCode()。
2)实现IEquatable不会重载==和!=自动操作,但没有什么可以阻止您这样做,就像System.String所做的那样。但是,如果这样做的话,您应该非常清楚地记录这一点,并且在比较仍将使用标识比较的其他引用类型(如mytype和object)时要小心。我怀疑这样做不是一个好主意,除非它将在您的代码中被大量使用,在那里每个人都将变得非常熟悉它,在那里重载==的语法结构将真正对可读性产生积极影响。
- jon,实现类型iequatable是否有任何性能提升,例如在集合中调用contains方法?
- 是的,它可以避免铸造。对于值类型,它也将避免装箱和取消装箱。请参阅文档以了解collection。contains-it uses equalitycomparer。default,如果可能,它将使用iequatable实现。
- 是的,重载operator==和不是一个好主意!=提供值相等性检查(与默认引用相等性检查相比)。msdn文档建议您只对不可变类型执行此操作。还有一些涉及接口和运算符重载的问题。
- 有关这两个问题的更多信息,请参阅stackoverflow.com/questions/728434/…。