2010-03-15 14 views
18

Come si gestiscono i campi null nella funzione GetHashCode?GetHashCode su campi null?

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

XOR non è un buon modo di combinare codici hash. Per un approccio più robusto, vedere http://stackoverflow.com/questions/263400/what-is-the-best-algorithm-for-an-overridden-system-object-gethashcode –

risposta

3

Come suggerito da Jeff Yates, l'override della risposta fornirebbe lo stesso hash per (nome = null, address = "foo") come (name = "foo", address = null). Questi devono essere diversi. Come suggerito nel collegamento, qualcosa di simile al seguente sarebbe meglio.

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

In genere, si controlla nulla e utilizzare 0 per quella "parte" del codice hash se il campo è nullo:

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

(scusate il C# -ismo, non sono sicuro del nulla controlla equivalente in VB)

+0

np sul "csism". hai appena chiarito che il codice hash per null è 0. – Shimmy

+0

btw, se il campo di distinzione è un int, posso restituire l'int stesso invece del suo hashcode? sarebbe una cattiva idea? , ad esempio return ContactId^(Name == null? 0: Name.GetHashCode) (è un int)? – Shimmy

+2

L'unico requisito per i codici hash è che gli oggetti uguali restituiscono uguali codici hash. Dal momento che gli stessi valori sono uguali, restituire int come il proprio codice hash va bene. In effetti, questo è esattamente ciò che sembra fare Int32.GetHashCode ...! – itowlson