Он использует IEqualityComparer<T>
( EqualityComparer<T>.Default
если вы не укажете другой при строительстве).
Когда вы добавляете элемент в набор, он найдет хэш-код с помощью IEqualityComparer<T>.GetHashCode
и сохранит как хеш-код, так и элемент (конечно, после проверки, есть ли элемент уже в наборе).
Чтобы найти элемент, он сначала будет использовать IEqualityComparer<T>.GetHashCode
для поиска хэш-кода, а затем для всех элементов с одинаковым хеш-кодом он будет использовать IEqualityComparer<T>.Equals
для сравнения на предмет фактического равенства.
Это означает, что у вас есть два варианта:
- Передайте кастом
IEqualityComparer<T>
в конструктор. Это лучший вариант, если вы не можете изменить T
саму себя или если вы хотите, чтобы отношение равенства отличалось от установленного по умолчанию (например, «все пользователи с отрицательным идентификатором пользователя считаются равными»). Это почти никогда не реализуется в самом типе (т.е. Foo
не реализуется IEqualityComparer<Foo>
), а в отдельном типе, который используется только для сравнения.
- Реализуйте равенство в самом типе, переопределив
GetHashCode
и Equals(object)
. В идеале также реализовать IEquatable<T>
в типе, особенно если это тип значения. Эти методы будут вызываться компаратором проверки на равенство по умолчанию.
Обратите внимание, что все это не относится к упорядоченному сравнению - что имеет смысл, поскольку, безусловно, есть ситуации, когда вы можете легко указать равенство, но не полное упорядочение. Это все то же самое Dictionary<TKey, TValue>
, в принципе.
Если вам нужен набор, в котором используется упорядочение, а не просто сравнение на равенство, вы должны использовать SortedSet<T>
из .NET 4, который позволяет вам указывать IComparer<T>
вместо IEqualityComparer<T>
. Это будет использовать IComparer<T>.Compare
- который будет делегировать IComparable<T>.CompareTo
или, IComparable.CompareTo
если вы используете Comparer<T>.Default
.
IEqualityComparer<T>
в конструктор или реализуйте ее в классеa
. msdn.microsoft.com/en-us/library/bb301504(v=vs.110).aspx