【问题标题】:What is the default equality comparer for a set type?集合类型的默认相等比较器是什么?
【发布时间】:2021-06-02 23:46:25
【问题描述】:

HashSet 构造函数的 MSDN API 中,它没有声明任何参数

初始化 HashSet 类的新实例,该实例为空且 使用集合类型的默认相等比较器。

集合类型的默认相等比较器是什么,例如对于自定义类?

顺便说一句:仅仅是我还是 MSDN API 文档的解释真的有点薄?我在阅读时不止一次偶然发现了这样的问题。

【问题讨论】:

    标签: c#


    【解决方案1】:

    这意味着它将使用EqualityComparer<T>.Default返回的比较器作为集合的元素类型T

    如文档所述:

    Default 属性检查类型 T 是否实现 System.IEquatable 接口,如果是,则返回一个 使用该实现的 EqualityComparer。否则,它 返回一个使用覆盖的 EqualityComparer T 提供的 Object.Equals 和 Object.GetHashCode。

    因此,对于您的自定义类型,它将使用您定义的GetHashCode 方法来定位集合中的项目。如果你已经实现了IEquatable<T>,它将使用IEquatable<T>.Equals(T) 来表示相等,否则它将使用你的Equals(object) 方法。此方法默认引用 object 类中定义的相等性。因此,如果您使用任一方法定义相等性,则应确保也覆盖 GetHashCode

    【讨论】:

    • 只是一个评论。如果CustomClass 没有覆盖GetHashCode()EqualityComparer<CustomClass>.Default 将发生故障(因此HashSet<CustomClass> 将发生故障)。
    • @JeppeStigNielsen 这是一个很好的观点,我刚刚在我写的一个小例子中偶然发现。为什么实施IEquatable<CustomClass> 还不够? Lee 的回答中的声明说,首先它会查找是否实现了IEquatable,如果没有实现,将使用Object.EqualsObject.GetHashCode
    • @JohnThreepwood - GetHashCode 总是被使用,Equals 使用的版本取决于类是否实现了IEquatable<T>
    • @JohnThreepwood 好吧,它需要为每个项目设置一个哈希码,它不会检查您的 IEquatable<> Equals 方法的主体以查看它是否可以提出哈希码算法从那!!那么它是如何工作的呢?很遗憾在这种情况下您没有收到编译器警告,就像您在没有覆盖 GetHashCode() 的情况下覆盖 Equals(object) 时收到的警告一样。
    【解决方案2】:

    默认情况下,它将委托给EqualityComparer<T>.Default。这将返回一个比较器,它可以比较两个 T 类型的对象。

    对于自定义类,它按以下顺序执行一些操作:

    • 如果该类实现了IEquatable<T>,它将委托给该类的该接口实现
    • 如果类定义了Equals 方法,它将使用该方法
    • 作为最后的手段,它将使用引用相等

    【讨论】:

      猜你喜欢
      • 2021-04-16
      • 2019-02-11
      • 2022-01-04
      • 1970-01-01
      • 2015-09-16
      • 2010-12-20
      • 1970-01-01
      • 1970-01-01
      • 2014-07-28
      相关资源
      最近更新 更多