2013-06-20 40 views
21

Trong C Sharp .NET có phương thức Equals và phương pháp SetEquals. Sự khác biệt ở đâu?Tại sao có phương thức equals riêng cho các bộ?

Đến từ Java, ý tưởng đầu tiên của tôi là SetEquals là không cần thiết, chỉ cần sử dụng phương thức Equals cho tất cả các đối tượng.

+1

bạn có nghĩa là 'ISet .SetEquals' http://msdn.microsoft.com/en-us/library/dd412096.aspx? – Jodrell

+2

tôi nghĩ rằng tài liệu hướng dẫn khá rõ ràng về sự khác biệt là gì. –

Trả lời

32

SetEquals không tuân theo cùng một hợp đồng như Equals. Đặc biệt nó không đối xứng, vì đối số chỉ là IEnumerable<T> thay vì ISet<T>. Điều này cho phép bạn kiểm tra mức độ bình đẳng đã đặt trong khi chỉ có một thiết lập. Xem xét:

List<int> intList = new List<int> { 1, 2, 3 }; 
HashSet<int> intSet = new HashSet<int>(intList); 

Bây giờ chúng ta có thể sử dụng:

Console.WriteLine(intSet.SetEquals(intList)); 

... nhưng chúng tôi không thể thực hiện Equals trong cùng một cách mà không thực thi các hành vi tương tự trên List<int> và mỗi IEnumerable<T> thực hiện khác.

Thậm chí nếu chúng tôi hạn chế nó cho các bộ khác, có một câu hỏi thú vị về sự bình đẳng thực sự có ý nghĩa gì. Ví dụ: xem xét hai bộ HashSet<string> có chứa các chuỗi giống nhau, nhưng có các trình so sánh bình đẳng khác nhau. (Có lẽ là một trong những trường hợp nhạy cảm và một là không.) Là những người bình đẳng, hay không? SetEquals quản lý để tránh các câu hỏi triết học như vậy bằng cách tránh cố gắng quá chung chung.

Điều gì về một số HashSet<int>SortedSet<int>? Họ có thể bằng nhau không? Chúng có thể có cùng giá trị - nhưng thứ tự của một giá trị không xác định.

Nhìn chung, ý tưởng của Object.EqualsObject.GetHashCode quá rộng trong chế độ xem của tôi. Thông thường, bạn muốn có một loại cụ thể về sự bình đẳng - và thường không có ý nghĩa gì khi so sánh các đối tượng bình đẳng ngay từ đầu. Điều này có thể dễ dàng hình thành các chủ đề của một rant hoàn toàn khác nhau, nhưng trong khi chờ đợi tôi ít nhất là vui mừng rằng NET đã không cố gắng áp dụng ý tưởng này quá rộng để bộ sưu tập. Khả năng sử dụng SetEquals với ý nghĩa được xác định rõ là hữu ích hơn, IMO.

3

Equals kiểm tra tính bình đẳng tham chiếu giữa hai và SetEquals sẽ kiểm tra các yếu tố trên bộ sưu tập.

10

HashSet<T>.SetEquals xác định xem HashSet có chứa các phần tử giống như một số IEnumerable<T> nhất định hay không. Nhưng tại sao nó trở lại đúng nếu các loại khác nhau?

HashSet<int> h = new HashSet<int>(); 
h.Add(0); 
h.Add(1); 
int[] ints = new[] { 0, 1, 1, 0 }; 
h.SetEquals(ints); // true, ignores duplicates because it's a set 
h.Equals(ints); // false, correct because not even the same types 

MSDN:

Phương pháp SetEquals bỏ qua các mục trùng lặp và thứ tự của yếu tố trong tham số khác .....

Kể từ HasetSet<T> không ghi đè Equals nó sử dụng cái được thừa kế từ đối tượng mà chỉ so sánh các tham chiếu. Vì vậy, nếu hai đối tượng không phải là cùng một tham chiếu, nó trả về false.

5
  • Equals sẽ kiểm tra nếu hai HashSet s là cùng một đối tượng.
  • SetEquals chụp trong một IEnumerable<T>, Điều đó nghĩa là: "Phương thức SetEquals bỏ qua các mục trùng lặp và thứ tự các phần tử trong thông số khác".

Vì vậy, SetEquals là để kiểm tra xem bạn đã tải một IEnumerable vào một HashSet, nó sẽ tạo cùng HashSet làm nguồn của bạn.

0

SetEquals:

Kiểm tra nếu HashSet chứa các yếu tố tương tự như một trao IEnumerable <T>.

Phương thức SetEquals xử lý tập hợp thứ hai như thể không có phần tử trùng lặp. Nếu có các phần tử trùng lặp, hai bộ sưu tập có thể vẫn được coi là bằng nhau.

Equals:

Equals thực sự là một thử nghiệm tham chiếu

List<string> stringList = new List<string> { "a", "b", "c" }; 
SortedSet<string> stringSet = new SortedSet<string> { "a", "b", "c" }; 

bool a = stringSet.SetEquals(stringList); 
// See if the two collections contain the same elements. 
0

Các ISet<T>.SetEquals thực hiện

Xác định xem các thiết lập hiện tại và thu quy định chứa cùng các yếu tố.

Việc thực hiện các Equals thừa hưởng từ object

là tương đương với một cuộc gọi đến phương pháp ReferenceEquals.

được thừa hưởng ReferenceEquals thực hiện,

Xác định xem các trường hợp đối tượng quy định là những ví dụ tương tự.


Trong paticular, lưu ý rằng trình tự truyền cho SetEqualsIEnumerable<T> có thể có một hoặc nhiều trường hợp của mọi thành viên của bộ này, trong bất kỳ thứ tự, và SetEquals vẫn sẽ trở thành sự thật.


Nếu bạn muốn xác nhận rằng hai chuỗi chứa chính xác cùng một thành viên theo thứ tự bạn có thể sử dụng tiện ích mở rộng SequenceEqual.

0
public static void Main(string[] args) 
     { 
      Console.WriteLine("Hello World!"); 

      System.Collections.Generic.HashSet<int> setA= new System.Collections.Generic.HashSet<int>(); 
      setA.Add(1); 
      System.Collections.Generic.HashSet<int> setB= new System.Collections.Generic.HashSet<int>(); 
      setB.Add(1); 


      Console.WriteLine("Equals method returns {0}", setA.Equals(setB)); 
      Console.WriteLine("SetEquals method returns {0}", setA.SetEquals(setB)); 


      Console.Write("Press any key to continue . . . "); 
      Console.ReadKey(true); 
     } 

Tạo đầu ra: Bằng phương thức trả về False phương pháp SetEquals trả về True

Các bằng phương pháp do đó có vẻ là một bài kiểm tra về bình đẳng tham chiếu.

Các vấn đề liên quan