22

如何处理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
4

2 回答 2

36

通常,如果字段为 null,则检查 null 并使用 0 作为哈希码的“部分”:

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

(请原谅 C#-ism,不确定 VB 中的空检查等效项)

于 2010-03-15T02:38:13.833 回答
14

正如 Jeff Yates 所建议的那样,答案中的覆盖将为 (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;
}

覆盖 System.Object.GetHashCode 的最佳算法是什么?

于 2017-01-30T21:39:43.760 回答