2010-03-15 19 views
18

GetHashCode işlevindeki boş alanlarla nasıl baş edebilirim?Boş alanları GetHashCode?

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 karma kodların iyi bir yol değildir. Daha sağlam bir yaklaşım için bkz. Http://stackoverflow.com/questions/263400/what-is-the-best-algorithm-for-an-overridden-system-object-gethashcode –

cevap

3

Jeff Yates'in önerdiği gibi, yanıttaki geçersiz kılma, (name = null, address = "foo") için aynı hash değerini verir (ad = "foo", address = null). Bunlar farklı olmalı. Bağlantıda önerildiği gibi, aşağıdakine benzer bir şey daha iyi olurdu.

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

Genellikle, boş olup olmadığını kontrol ve alan boş ise karma kod bu "parçası" için 0 kullanın:

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

(null emin değil C# -ism pardon VB'ye eşdeğerde eşdeğer)

+0

np 'csism' hakkında. Sadece null için karma kodunun 0 olduğunu – Shimmy

+0

btw, ayırıcı alan bir int ise, inh kodu yerine int'yi iade edebilir miyim? Bu kötü bir fikir olur mu? , yani ContactId^i döndürür (Name == null? 0: Name.GetHashCode) (int)? – Shimmy

+2

Karma kodlar için tek gereklilik, eşit nesnelerin eşit karma kodları döndürmesidir. Eşit eşitlikler eşit olduğundan, int kendi karma kodu olarak döndürüldüğünde iyidir. Gerçekten de, bu Int32.GetHashCode'un yaptığı gibi ... – itowlson