空字段上的GetHashCode?

Shi*_*mmy 19 null equality iequatable gethashcode nullreferenceexception

我如何处理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
Run Code Online (Sandbox Code Playgroud)

ito*_*son 32

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

return (Name == null ? 0 : Name.GetHashCode()) ^ 
  (Address == null ? 0 : Address.GetHashCode());
Run Code Online (Sandbox Code Playgroud)

(原谅C#-ism,不确定VB中的null check等价物)

  • XORing不是组合哈希码的好方法.有关更强大的方法,请参阅http://stackoverflow.com/questions/263400/what-is-the-best-algorithm-for-an-overridden-system-object-gethashcode (3认同)
  • 对哈希码的唯一要求是等对象返回相等的哈希码.由于相等的int是相等的,所以将int作为自己的哈希码返回就可以了.实际上,这正是Int32.GetHashCode似乎所做的......! (2认同)

小智 7

正如杰夫·耶茨(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;
}
Run Code Online (Sandbox Code Playgroud)

重写System.Object.GetHashCode的最佳算法是什么?

  • ((Name == null?0:Name.GetHashCode())可以在C#7中压缩为`(Foo?.GetHashCode()?? 0)` (2认同)