Bởi vì nó mang lại cho chúng tôi cái gì đó hữu ích. Hãy xem xét những điều sau đây:
var countSameName = from p in PersonInfoStore
group p.Id by new {p.FirstName, p.SecondName} into grp
select new{grp.Key.FirstName, grp.Key.SecondName, grp.Count()};
Các công trình vì việc thực hiện Equals()
và GetHashCode()
với nhiều loại vô danh hoạt động trên cơ sở các lĩnh vực-by-lĩnh vực bình đẳng.
- Điều này có nghĩa là ở trên sẽ gần giống với truy vấn tương tự khi chạy với số
PersonInfoStore
không phải là đối tượng LINQ. (Vẫn không giống nhau, nó sẽ khớp với những gì một nguồn XML sẽ làm, nhưng không phải những gì mà hầu hết các collations của cơ sở dữ liệu sẽ dẫn đến).
- Nó có nghĩa là chúng ta không cần phải xác định một
IEqualityComparer
cho mỗi cuộc gọi đến GroupBy
đó sẽ làm cho nhóm bởi thực sự khó khăn với các đối tượng ẩn danh - đó là có thể, nhưng không dễ dàng để xác định một IEqualityComparer cho các đối tượng ẩn danh - và xa ý nghĩa tự nhiên nhất .
- Trên tất cả, nó không gây ra sự cố với hầu hết các trường hợp.
Điểm thứ ba đáng xem.
Khi xác định loại giá trị, chúng tôi tự nhiên muốn có khái niệm bình đẳng dựa trên giá trị. Mặc dù chúng ta có thể có một ý tưởng khác về sự bình đẳng dựa trên giá trị đó so với mặc định, chẳng hạn như khớp một trường cụ thể không phân biệt, mặc định là tự nhiên hợp lý (nếu hiệu suất kém và lỗi trong một trường hợp *). (Ngoài ra, bình đẳng tham chiếu là vô nghĩa trong trường hợp này).
Khi xác định loại tham chiếu, chúng tôi có thể hoặc không muốn có khái niệm bình đẳng dựa trên giá trị. Mặc định cho chúng ta sự bình đẳng tham chiếu, nhưng chúng ta có thể dễ dàng thay đổi điều đó. Nếu chúng tôi thay đổi nó, chúng tôi có thể thay đổi nó chỉ Equals
và GetHashCode
hoặc cho họ và cũng ==
.
Khi chúng tôi xác định loại ẩn danh, hãy đợi, chúng tôi đã không xác định, đó là điều vô danh! Hầu hết các kịch bản mà chúng tôi quan tâm về bình đẳng tham chiếu không còn nữa. Nếu chúng ta sẽ giữ một vật thể xung quanh đủ lâu để sau này tự hỏi liệu nó có giống với một vật thể khác không, chúng ta có lẽ sẽ không đối phó với một vật thể vô danh nào. Các trường hợp mà chúng tôi quan tâm về bình đẳng dựa trên giá trị xuất hiện rất nhiều. Rất thường với LINQ (GroupBy
như chúng ta đã thấy ở trên, mà còn Distinct
, Union
, GroupJoin
, Intersect
, SequenceEqual
, ToDictionary
và ToLookup
) và thường với mục đích khác (nó không giống như chúng tôi đã không làm những điều LINQ làm cho chúng ta với enumerables trong 2.0 và ở một mức độ nào đó trước đó, bất kỳ ai viết mã bằng 2.0 có thể đã viết một nửa các phương pháp trong số Enumerable
mình).
Trong tất cả, chúng tôi thu được rất nhiều từ cách thức hoạt động bình đẳng với các lớp ẩn danh.
Trong cơ hội không có ai đó thực sự muốn tham chiếu bình đẳng, ==
bằng cách sử dụng bình đẳng tham chiếu có nghĩa là họ vẫn có điều đó, vì vậy chúng tôi không mất bất cứ điều gì. Đó là con đường để đi.
* Việc triển khai mặc định Equals()
và GetHashCode()
có tối ưu hóa cho phép sử dụng kết hợp nhị phân trong trường hợp an toàn để thực hiện việc này. Thật không may có một lỗi mà làm cho nó đôi khi mis-xác định một số trường hợp là an toàn cho phương pháp này nhanh hơn khi họ không (hoặc ít nhất là nó được sử dụng để, có thể nó đã được cố định). Một trường hợp phổ biến là nếu bạn có trường decimal
, trong một cấu trúc, thì nó sẽ xem xét một số trường hợp có trường tương đương là không bằng nhau.
Đây là một trong số ít bài đăng trên SO có 3 câu trả lời trở lên, trong đó đại diện trung bình. của những người trả lời là hơn ** 95k **, từ tháng 5 đến 23-2017. – dotNET