18

Как я могу работать с нулевыми полями в функции GetHashCode?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 не является хорошим способом объединения хэш-коды. Для более надежного подхода см. Http://stackoverflow.com/questions/263400/what-is-the-best-algorithm-for-an-overridden-system-object-gethashcode –

ответ

3

Как предположил Джефф Йейтс, переопределение в ответе даст такой же хэш для (name = null, address = "foo") как (name = "foo", address = null). Они должны быть разными. Как было предложено в ссылке, что-то похожее на следующее было бы лучше.

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

Как правило, проверить нуль и использовать 0 для этой «части» хэш-кода, если поле равно нулю:

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

(простите C# -изм, не уверены в нуль проверьте эквивалент в VB)

+0

np о «csism». вы просто уточнили, что хэш-код для null равен 0. – Shimmy

+0

Кстати, если поле отличия есть int, могу ли я вернуть сам int вместо его hashcode? это будет плохая идея? i.e. return ContactId^(Name == null? 0: Name.GetHashCode) (это int)? – Shimmy

+2

Единственным требованием для хеш-кодов является то, что равные объекты возвращают равные хэш-коды. Поскольку равные ints равны, возвращает int, поскольку его собственный хэш-код является точным. Действительно, это именно то, что делает Int32.GetHashCode ...! – itowlson

Смежные вопросы