我有一堂课是IComparable:
IComparable
public class a : IComparable { public int Id { get; set; } public string Name { get; set; } public a(int id) { this.Id = id; } public int CompareTo(object obj) { return this.Id.CompareTo(((a)obj).Id); } }
当我将此类的对象列表添加到哈希集时:
a a1 = new a(1); a a2 = new a(2); HashSet<a> ha = new HashSet<a>(); ha.add(a1); ha.add(a2); ha.add(a1);
一切都很好,ha.count还是2,但是:
ha.count
2
a a1 = new a(1); a a2 = new a(2); HashSet<a> ha = new HashSet<a>(); ha.add(a1); ha.add(a2); ha.add(new a(1));
现在ha.count是3。
3
HashSet
a
CompareTo
它使用一个IEqualityComparer<T>(EqualityComparer<T>.Default除非您在构造上指定了另一个)。
IEqualityComparer<T>
EqualityComparer<T>.Default
将元素添加到集合中时,它将使用来查找哈希码IEqualityComparer<T>.GetHashCode,并存储哈希码和元素(当然,在检查元素是否已在集合中之后)。
IEqualityComparer<T>.GetHashCode
要查找一个元素,它将首先使用IEqualityComparer<T>.GetHashCode来查找哈希码,然后对于具有相同哈希码的所有元素,它将IEqualityComparer<T>.Equals用于比较实际相等性。
IEqualityComparer<T>.Equals
这意味着您有两个选择:
T
Foo
IEqualityComparer<Foo>
GetHashCode
Equals(object)
IEquatable<T>
请注意,从 顺序 比较的角度来看,这些都不是什么-这很有意义,因为在某些情况下,您可以轻松指定相等性但不能指定总顺序。Dictionary<TKey, TValue>基本上与都一样。
Dictionary<TKey, TValue>
如果要使用 排序 而不是相等比较的集合,则应SortedSet<T>从.NET 4 使用- 允许您指定一个IComparer<T>而不是一个IEqualityComparer<T>。这将使用IComparer<T>.Compare-将委派给,IComparable<T>.CompareTo或者IComparable.CompareTo如果您正在使用Comparer<T>.Default。
SortedSet<T>
IComparer<T>
IComparer<T>.Compare
IComparable<T>.CompareTo
IComparable.CompareTo
Comparer<T>.Default