Nó sử dụng một IEqualityComparer<T>
( EqualityComparer<T>.Default
trừ khi bạn chỉ định một cái khác trong xây dựng).
Khi bạn thêm một phần tử vào tập hợp, nó sẽ tìm mã băm bằng cách sử dụng IEqualityComparer<T>.GetHashCode
và lưu trữ cả mã băm và phần tử (tất nhiên sau khi kiểm tra xem phần tử đó đã có trong tập chưa, tất nhiên).
Để tìm một phần tử, trước tiên, nó sẽ sử dụng IEqualityComparer<T>.GetHashCode
để tìm mã băm, sau đó cho tất cả các phần tử có cùng mã băm, nó sẽ sử dụng IEqualityComparer<T>.Equals
để so sánh cho sự bình đẳng thực tế.
Điều đó có nghĩa là bạn có hai lựa chọn:
- Truyền một tùy chỉnh
IEqualityComparer<T>
vào các nhà xây dựng. Đây là tùy chọn tốt nhất nếu bạn không thể sửa đổi T
chính nó hoặc nếu bạn muốn có mối quan hệ bình đẳng không mặc định (ví dụ: "tất cả người dùng có ID người dùng âm được coi là bằng nhau"). Điều này gần như không bao giờ được thực hiện trên chính loại đó (tức là Foo
không thực hiện IEqualityComparer<Foo>
) nhưng trong một loại riêng biệt chỉ được sử dụng để so sánh.
- Thực hiện bình đẳng trong chính loại, bằng cách ghi đè
GetHashCode
và Equals(object)
. Lý tưởng nhất là thực hiện IEquatable<T>
theo kiểu, đặc biệt nếu đó là loại giá trị. Các phương thức này sẽ được gọi bằng bộ so sánh đẳng thức mặc định.
Lưu ý rằng không có gì trong số này là về mặt so sánh theo thứ tự - điều này có ý nghĩa, vì chắc chắn có những tình huống mà bạn có thể dễ dàng xác định đẳng thức nhưng không phải là tổng thứ tự. Điều này hoàn toàn giống như Dictionary<TKey, TValue>
, về cơ bản.
Nếu bạn muốn một tập hợp sử dụng thứ tự thay vì chỉ so sánh bằng, bạn nên sử dụng SortedSet<T>
từ .NET 4 - cho phép bạn chỉ định một IComparer<T>
thay vì một IEqualityComparer<T>
. Điều này sẽ sử dụng IComparer<T>.Compare
- sẽ ủy thác IComparable<T>.CompareTo
hoặc IComparable.CompareTo
nếu bạn đang sử dụng Comparer<T>.Default
.
IEqualityComparer<T>
trong hàm tạo hoặc thực hiện nó trong lớpa
. msdn.microsoft.com/en-us/l