2015-06-07 13 views
6
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 

namespace Crystal_Message 
{ 
    class Person 
    { 
     private string firstName =""; 
     private string lastName= ""; 
     private string phone=""; 


     public Person(string firstName, string lastName, string phone) 
     { 
      this.FirstName = firstName; 
      this.LastName = lastName; 
      this.PhoneNumber = phone; 
     } 

     public string FirstName 
     { 
      get { return firstName; } 

      private set 
      { 
       if (string.IsNullOrWhiteSpace(value)){ 

        throw new ArgumentNullException("Must Include First Name"); 
       } 

       this.firstName = value; 
      } 

     } 

     public string LastName 
     { 
      get { return lastName; } 

      private set 
      { 
       if (string.IsNullOrWhiteSpace(value)){ 

        throw new ArgumentNullException("Must Include Last Name"); 
       } 

       this.lastName = value; 
      } 

     } 

     public string PhoneNumber 
     { 
      get { return phone; } 

      private set 
      { 
       if (string.IsNullOrWhiteSpace(value)){ 

        throw new ArgumentNullException("Must Include Phone Number"); 
       } 

       this.phone = value; 
      } 

     } 


     public override string ToString() 
     { 
      return "First Name: " + this.FirstName + " " + " Last Name: " + this.LastName + " " + " Phone Number: " + this.PhoneNumber; 
     } 

     public override bool Equals(object obj) 
     { 
      if(obj == null) 
      { 
       return false; 
      } 

      Person testEquals = obj as Person; 

      if((System.Object)testEquals == null) 
      { 
       return false; 
      } 

      return (this.firstName == testEquals.firstName) && (this.lastName == testEquals.lastName) && (this.phone == testEquals.phone); 

     } 

     /* 
     public override int GetHashCode() 
     { 
      return 
     } 
     */ 
    } 
} 

Tôi đã làm theo các hướng dẫn của MSDN. Hai câu hỏi:C# Thực hiện Phương thức Bằng Chính xác và Làm cách nào để triển khai Phương thức GetHashCode

  1. Tôi đã triển khai đúng phương thức bằng?
  2. Ai đó có thể chỉ cho tôi cách triển khai GetHashCode đúng cho lớp học của tôi không? MSDN không x^y, nhưng tôi không thể làm điều đó cho tôi.
+2

Chắc chắn bạn có thể sử dụng XOR, sử dụng nó trên mã băm của các thành viên. Bạn không cần phải làm vậy, chỉ cần trả lại điện thoại.GetHashCode(). Điều đó hoạt động tốt bởi vì mọi người đều có số điện thoại duy nhất. –

+0

Cảm ơn, phương pháp equals của tôi, bất kỳ cải tiến nào, hoặc tôi đã thực hiện nó một cách chính xác? Nó có thể trở thành một vấn đề, bởi vì hai người có thể có cùng một số, sống trong cùng một ngôi nhà. –

+0

@HansPassant Không phải ai cũng có số điện thoại duy nhất. Một số người có thể chọn không nhập số điện thoại của họ ngay cả khi họ có số điện thoại, những người khác có thể chia sẻ số điện thoại (công ty hoặc điện thoại gia đình). – hvd

Trả lời

1

Một phương pháp phổ biến hơn là một xor mã băm đơn giản, như được đăng trong câu trả lời của Filip, là sử dụng một công thức phức tạp hơn để kết hợp chúng. Nhân mã băm các lĩnh vực cá nhân của các số khác nhau, ví dụ như vậy:

public override int GetHashCode() 
{ 
    unchecked 
    { 
     return (firstName.GetHashCode() * 33^lastName.GetHashCode()) * 33^phone.GetHashCode(); 
    } 
} 

(Lưu ý unchecked keyword:. Tràn số nguyên dự kiến ​​ở đây, và im lặng bao quanh là chính xác hành vi dự định)

Nó có lẽ sẽ không tạo ra sự khác biệt cho các loại bê tông bạn đang xử lý, nhưng nói chung, nó tốt hơn. Hãy xem xét một kiểu đơn giản chỉ chứa hai giá trị số nguyên. Cũng xem xét rằng việc thực hiện GetHashCode() của int chỉ đơn giản trả về giá trị của riêng nó. Nếu bạn sử dụng một xor đơn giản để kết hợp các giá trị, bạn sẽ có rất nhiều va chạm băm cho mã bình thường: ví dụ đơn giản nhất là mỗi cặp của hai giá trị giống nhau sẽ tạo ra cùng một mã băm bằng không.

Tính toán ở đây thực sự là phép tính được thực hiện bởi Tuple<T1, T2, T3>. Tôi đã không viết nó theo cách của Microsoft, nhưng các phép tính thực tế và các con số phải giống nhau.

+0

Cảm ơn vì điều này. Bạn có đề nghị tôi làm điều này cho các lớp khác của tôi không? Tôi có một lớp nhân viên và lớp thông báo. –

+0

@Nexusfactor Tôi nghĩ rằng miễn là nó làm cho nó dễ dàng hơn để xác minh rằng thực hiện của bạn 'GetHashCode()' là chính xác, sau đó có thực sự không có lý do không làm như vậy. Nhưng nếu bạn thấy nó như là một biến chứng thêm, và việc triển khai mã băm của riêng bạn là đủ tốt, thì tôi chắc chắn có thể hiểu được việc thực thi mã băm của riêng bạn. – hvd

+0

Cảm ơn bạn rất nhiều vì đã dành thời gian và giải thích. Phần lớn được chiếm đoạt. Chỉ tò mò thôi, bạn có học được điều này từ một cuốn sách hướng dẫn/sách không? hoặc trường học? Rất thích đọc thêm về nó cho sự hiểu biết của riêng tôi. –

6

Vâng, để không gặp phải bất kỳ sự cố nào, GetHashCode nên sử dụng tất cả các thành viên Equals sử dụng và ngược lại.

Vì vậy, trong trường hợp của bạn:

public override int GetHashCode() 
{ 
    return firstName.GetHashCode()^lastName.GetHashCode()^phone.GetHashCode(); 
} 
+0

Tôi nghĩ rằng đây là một cách tiếp cận tốt đẹp. Ngay cả khi hai người có cùng một số, họ và tên khác nhau để tạo ra một HashCode duy nhất chính xác? –

+0

@Nexusfactor yes, miễn là ít nhất một trong các trường của bạn là khác nhau ... – Filip

+0

Bạn có nghĩ rằng, chỉ cần khắc phục, tôi nên thêm ID int cá nhân, id duy nhất # cho mọi người? Chỉ trong trường hợp có một cơ hội một người từ cùng một ngôi nhà có thể có cùng tên (đầu tiên và cuối cùng) ví dụ, một đứa con trai có thể được đặt tên theo sau là cha. Tuy nhiên, cả hai đều phải có ID khác nhau. –

1

giữ tốt nhất trong tâm trí những gì mục đích của hai phương pháp này là: Với bằng BẠN xác định theo đó hoàn cảnh hai trường hợp của lớp học của bạn phải được coi là, tốt, bình đẳng . Vì vậy, nếu trong trường hợp của bạn, đây là tên đầu tiên, họ và số điện thoại bằng nhau thì điều này là chính xác. Phương pháp băm lần lượt được sử dụng để sắp xếp hoặc phân phối các trường hợp của bạn, ví dụ: trong bản đồ băm. Nó phải nhanh và đủ tốt để tránh việc phân cụm không mong muốn. Do đó, bạn thường thấy các giá trị nhân với số nguyên tố trong hàm băm. Bạn phải đảm bảo rằng các đối tượng bằng nhau có cùng mã băm nhưng không phải ngược lại. Vì vậy, các đối tượng khác nhau có thể có cùng mã băm.

+0

"Vì vậy, các đối tượng khác nhau có thể có cùng mã băm" - trong trường hợp đó bạn có thể gặp sự cố khi sử dụng HashSet. Bởi vì nó sẽ gọi GetHashCode và giả định rằng đối tượng này đã tồn tại trong bộ và sẽ không thêm nó. Nhưng trong thực tế những đối tượng đó không trùng lặp ... – Filip

+0

Xem https://msdn.microsoft.com/library/system.object.gethashcode%28v=vs.110%29.aspx –

+0

Liên kết bằng một ngôn ngữ khác. –

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