2011-12-15 18 views
5

Đây là trình so sánh bình đẳng mà tôi vừa viết vì tôi muốn có một bộ các mục riêng biệt từ một danh sách chứa các thực thể.Câu hỏi về IEqualityComparer <T>/Danh sách <T> .Distinct()

class InvoiceComparer : IEqualityComparer<Invoice> 
    { 
     public bool Equals(Invoice x, Invoice y) 
     { 
      // A 
      if (Object.ReferenceEquals(x, y)) return true; 

      // B 
      if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null)) return false; 

      // C 
      return x.TxnID == y.TxnID; 
     } 

     public int GetHashCode(Invoice obj) 
     { 
      if (Object.ReferenceEquals(obj, null)) return 0; 
      return obj.TxnID2.GetHashCode(); 
     } 
    } 
  1. Tại sao Distinct đòi hỏi một Comparer như trái ngược với một Func<T,T,bool>?
  2. Có (A) và (B) bất kỳ điều gì khác ngoài tối ưu hóa và có các tình huống khi chúng không hoạt động theo cách mong đợi, do tính phụ thuộc trong so sánh các tham chiếu không?
  3. Nếu tôi muốn, tôi có thể thay thế (C) với

    return GetHashCode(x) == GetHashCode(y)

+0

quan sát ngẫu nhiên tự agrandizing: điều này có thể làm cho một thi tốt quetion –

Trả lời

4
  1. Vì vậy, nó có thể sử dụng hashcodes là O (n) như trái ngược với O (n )
  2. (A) là một tối ưu hóa.
    (B) là cần thiết; nếu không, nó sẽ ném một số NullReferenceException. Nếu Invoice là cấu trúc, tuy nhiên, cả hai đều không cần thiết và chậm hơn.
  3. số hashcodes không độc đáo
+0

bộ não của tôi không hoạt động: tôi nghĩ rằng tôi đọc trong các tài liệu "đối tượng bằng nhau trả về mã băm bằng nhau" ... –

+0

@Gabriel: Các đối tượng bất bình đẳng _can_ cũng trả lại mã băm bằng nhau. – SLaks

1
  • A là một cách đơn giản và nhanh chóng để đảm bảo rằng cả hai đối tượng nằm ở cùng địa chỉ bộ nhớ vì vậy cả hai tài liệu tham khảo cùng một đối tượng.
  • B - nếu một trong các tài liệu tham khảo là null - obviuosly nó không thực hiện bất kỳ cảm giác làm bình đẳng so sánh
  • C - không, đôi khi GetHashCode() có thể trả về giá trị tương tự cho các đối tượng khác nhau (hash collision) vì vậy bạn nên làm bình đẳng so

về cùng giá trị mã băm cho các đối tượng khác nhau, MSDN:

Nếu hai vật thể so sánh như bình đẳng, phương pháp GetHashCode cho mỗi 01 Đối tượngphải trả về cùng một giá trị. Tuy nhiên, nếu hai đối tượng không so sánh như nhau, phương thức GetHashCode cho hai đối tượng không phải trả về các giá trị khác nhau.

0

Riêng biệt() về cơ bản hoạt động trên thuật ngữ "không bằng nhau". do đó, nếu danh sách của bạn chứa các kiểu non-primitiv, bạn phải thực hiện EqualityComparer của riêng bạn.

Tại A, bạn kiểm tra xem các đối tượng có giống hệt nhau hay không. Nếu hai đối tượng bằng nhau, chúng không phải giống hệt nhau, nhưng nếu chúng giống hệt nhau, bạn có thể chắc chắn rằng chúng bằng nhau. Vì vậy, phần A có thể làm tăng hiệu quả của phương pháp trong một số trường hợp.