2010-03-15 30 views
18

Làm cách nào để xử lý các trường rỗng trong hàm GetHashCode?GetHashCode trên các trường rỗng?

Module Module1 
    Sub Main() 
    Dim c As New Contact 
    Dim hash = c.GetHashCode 
    End Sub 

    Public Class Contact : Implements IEquatable(Of Contact) 
    Public Name As String 
    Public Address As String 

    Public Overloads Function Equals(ByVal other As Contact) As Boolean _ 
     Implements System.IEquatable(Of Contact).Equals 
     Return Name = other.Name AndAlso Address = other.Address 
    End Function 

    Public Overrides Function Equals(ByVal obj As Object) As Boolean 
     If ReferenceEquals(Me, obj) Then Return True 

     If TypeOf obj Is Contact Then 
     Return Equals(DirectCast(obj, Contact)) 
     Else 
     Return False 
     End If 
    End Function 

    Public Overrides Function GetHashCode() As Integer 
     Return Name.GetHashCode Xor Address.GetHashCode 
    End Function 
    End Class 
End Module 
+0

XORing không phải là một cách tốt để kết hợp mã băm. Để có cách tiếp cận mạnh mẽ hơn, hãy xem http://stackoverflow.com/questions/263400/what-is-the-best-algorithm-for-an-overridden-system-object-gethashcode –

Trả lời

3

Như Jeff Yates đã đề xuất, ghi đè trong câu trả lời sẽ cung cấp cùng một hàm băm cho (name = null, address = "foo") dưới dạng (name = "foo", address = null). Những thứ này cần phải khác nhau. Như đề xuất trong liên kết, một cái gì đó tương tự như sau sẽ tốt hơn.

public override int GetHashCode() 
{ 
    unchecked // Overflow is fine, just wrap 
    { 
     int hash = 17; 
     hash = hash * 23 + (Name == null ? 0 : Name.GetHashCode()); 
     hash = hash * 23 + (Address == null ? 0 : Address.GetHashCode()); 
    } 
    return hash; 
} 

What is the best algorithm for an overridden System.Object.GetHashCode?

30

Thông thường, bạn kiểm tra cho null và sử dụng 0 cho rằng "một phần" của mã băm nếu lĩnh vực này là null:

return (Name == null ? 0 : Name.GetHashCode())^
    (Address == null ? 0 : Address.GetHashCode()); 

(pardon C# -ism, không chắc chắn về null kiểm tra tương đương trong VB)

+0

np về 'csism'. bạn chỉ cần làm rõ rằng mã băm cho null là 0. – Shimmy

+0

btw, nếu trường phân biệt là int, tôi có thể trả về bản thân thay vì mã băm không? đó có phải là một ý tưởng tồi không? tức là trả lại ContactId^(Tên == null? 0: Name.GetHashCode) (đó là một int)? – Shimmy

+2

Yêu cầu duy nhất cho mã băm là các đối tượng bằng nhau trả lại mã băm bằng nhau. Vì ints bằng nhau bằng nhau, trả về int vì mã băm của nó là tốt. Thật vậy, đây chính xác là những gì Int32.GetHashCode xuất hiện để làm ...! – itowlson

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