【发布时间】:2021-06-02 23:46:25
【问题描述】:
在 HashSet 构造函数的 MSDN API 中,它没有声明任何参数
初始化 HashSet 类的新实例,该实例为空且 使用集合类型的默认相等比较器。
集合类型的默认相等比较器是什么,例如对于自定义类?
顺便说一句:仅仅是我还是 MSDN API 文档的解释真的有点薄?我在阅读时不止一次偶然发现了这样的问题。
【问题讨论】:
标签: c#
在 HashSet 构造函数的 MSDN API 中,它没有声明任何参数
初始化 HashSet 类的新实例,该实例为空且 使用集合类型的默认相等比较器。
集合类型的默认相等比较器是什么,例如对于自定义类?
顺便说一句:仅仅是我还是 MSDN API 文档的解释真的有点薄?我在阅读时不止一次偶然发现了这样的问题。
【问题讨论】:
标签: c#
这意味着它将使用EqualityComparer<T>.Default返回的比较器作为集合的元素类型T。
如文档所述:
Default 属性检查类型
T是否实现 System.IEquatable 接口,如果是,则返回一个 使用该实现的 EqualityComparer。否则,它 返回一个使用覆盖的 EqualityComparerT提供的 Object.Equals 和 Object.GetHashCode。
因此,对于您的自定义类型,它将使用您定义的GetHashCode 方法来定位集合中的项目。如果你已经实现了IEquatable<T>,它将使用IEquatable<T>.Equals(T) 来表示相等,否则它将使用你的Equals(object) 方法。此方法默认引用 object 类中定义的相等性。因此,如果您使用任一方法定义相等性,则应确保也覆盖 GetHashCode。
【讨论】:
CustomClass 没有覆盖GetHashCode(),EqualityComparer<CustomClass>.Default 将发生故障(因此HashSet<CustomClass> 将发生故障)。
IEquatable<CustomClass> 还不够? Lee 的回答中的声明说,首先它会查找是否实现了IEquatable,如果没有实现,将使用Object.Equals 和Object.GetHashCode。
GetHashCode 总是被使用,Equals 使用的版本取决于类是否实现了IEquatable<T>。
IEquatable<> Equals 方法的主体以查看它是否可以提出哈希码算法从那!!那么它是如何工作的呢?很遗憾在这种情况下您没有收到编译器警告,就像您在没有覆盖 GetHashCode() 的情况下覆盖 Equals(object) 时收到的警告一样。
默认情况下,它将委托给EqualityComparer<T>.Default。这将返回一个比较器,它可以比较两个 T 类型的对象。
对于自定义类,它按以下顺序执行一些操作:
IEquatable<T>,它将委托给该类的该接口实现Equals 方法,它将使用该方法【讨论】: