【问题标题】:Understanding IEquatable了解 IEquatable
【发布时间】:2010-09-29 12:24:18
【问题描述】:

当我使用IEquatable<T> interface 实现我想比较的对象时:

  1. 如果我已经实现了Equals(T),为什么还要重写Equals(object) 方法?
  2. 实现IEquatable<T> 后,我可以使用==!= 运算符吗?

【问题讨论】:

    标签: c# iequatable


    【解决方案1】:
    1. 来自MS Docs article on IEquatable<T>

      如果你实现IEquatable<T>,你还应该重写 的基类实现 Equals(Object)GetHashCode() 这样他们的行为是 与上述一致 Equals(T) 方法。如果你确实覆盖 Equals(Object),你的 重写的实现也是 调用静态 Equals(Object, Object) 在你的课堂上使用方法。此外, 你应该重载op_Equalityop_Inequality 运营商。 这确保了所有相等性测试 返回一致的结果。

    2. 不,operators do not use the Equals method。他们必须是 overloaded separately 才能这样做。

    【讨论】:

    • 所以当您处理对象时,== 假设仅表示完全相同的内存地址(相同实例)
    • 差不多。更多信息在这里:msdn.microsoft.com/en-us/library/53k8ybth(VS.80).aspx
    • 不,为此使用 ReferenceEquals()。等式运算符 (==) 通常含义相同,但可以被覆盖(例如,对于字符串等)。
    • 轻微的术语修正 - 您不能覆盖运算符,但可以重载它们。
    • 是的,您可以重载 == 和 != 并将它们与 IEquatable 接口结合使用。但这需要手动完成,IEquatable 不会自动提供。答案第 2 部分中的“否”实际上是不正确的。注意:尝试编辑答案,但显然有些人认为评分最高的答案不正确不足以批准更正编辑。
    【解决方案2】:

    1) 正如 Ray 所说,重写 Equals(object) 以确保从不知道(静态)您实现 IEquatable<T> 的类调用该方法时的一致性。例如,非泛型集合类将使用Equals(object) 进行比较。您还应该覆盖GetHashCode()

    2) 实现 IEquatable<T> 不会自动重载 == 和 != 运算符,但没有什么可以阻止您这样做,就像 System.String 一样。但是,如果您这样做,您应该非常清楚地记录这一点 - 并且在对仍将使用身份比较的其他类型的引用(例如 MyType 和 Object)进行比较时要小心。我怀疑这样做不是一个好主意,除非它在你的代码中是一个非常常用的类型,每个人都会非常熟悉它并且重载 == 的语法糖真的会对可读性产生积极影响。

    【讨论】:

    • Jon,IEquatable 实现类型在 Collection 中使用,调用 Contains 方法是否有任何性能提升?
    • 它会避免强制转换,是的。对于值类型,它也会避免装箱和拆箱。请参阅 Collection.Contains 的文档 - 它使用 EqualityComparer.Default,如果可能,它将使用 IEquatable 实现。
    • 是的,重载运算符 == 和 != 以提供值相等检查(相对于默认的引用相等检查)并不是一个好主意。 MSDN 文档建议您只对不可变类型执行此操作。还有涉及接口和运算符重载的问题。
    • 有关这两个问题的更多信息,请参见 stackoverflow.com/questions/728434/…
    猜你喜欢
    • 2020-06-30
    • 2020-08-24
    • 1970-01-01
    • 1970-01-01
    • 2016-04-24
    • 2023-01-26
    • 2016-12-30
    • 2011-09-11
    • 2014-12-31
    相关资源
    最近更新 更多