首页 文章

覆盖GetHashCode变体

提问于
浏览
1

我有一个理论类Name_Order,它有一个字符串 Name 和一个int Order .

我需要指出两个 Name_Order 是不同的,如果NameOrder对不同,那么,或者名称或顺序是不同的 .

现在,重写Equals没问题,但我有一些"issues"与GetHashCode:

Public Class Name_Order
  Public Property Name As String
  Public Property Order As Integer

  Public Overrides Function Equals(ByVal obj As Object) As Boolean
    If TypeOf obj Is Name_Order Then
      Dim no = DirectCast(obj, Name_Order)
      Return Me.Name = no.Name AndAlso Me.Order = no.Order
    Else
      Return MyBase.Equals(obj)
    End If
  End Function

  Public Overrides Function GetHashCode() As Integer
    Dim hcName = 0
    If Me.Name IsNot Nothing Then
      hcName = Me.Name.GetHashCode
    End If

    Dim hcOrder = Me.Order.GetHashCode

    Return hcName + hcOrder
  End Function
End Class

在这种情况下,对哈希码求和,留下一个(小但是真实的)可能性,即具有不同名称或顺序的两个不同的Name_Orders是“相同的” .

说,添加 7 154 给出与添加 154 7 相同的结果...

该方法的替代覆盖?

2 回答

  • 0

    首先,虽然避免碰撞是好的,但如果发生碰撞则不是问题 . 但常见的方法是:

    return 7 * x.GetHashCode() + y.GetHashCode();
    

    这在例如点/位置处更明显,其中避免明显的对角线碰撞(例如(2,3)vs(3,2))会很好 .

    代码中一个更大的问题是hash / equals中的属性是可变的;如果它们被改变,字典等中的任何用法都将停止工作 . 您应该更喜欢只读键值 .

  • 3

    MSDN在这里给出了该案例答案的变体(在Example的部分中):

    http://msdn.microsoft.com/en-us/library/bb338049.aspx

    Public Class Product
        Public Property Name As String
        Public Property Code As Integer
    End Class
    
    ' Custom comparer for the Product class
    Public Class ProductComparer
        Implements IEqualityComparer(Of Product)
    
        Public Function Equals1(
            ByVal x As Product, 
            ByVal y As Product
            ) As Boolean Implements IEqualityComparer(Of Product).Equals
    
            ' Check whether the compared objects reference the same data.
            If x Is y Then Return True
    
            'Check whether any of the compared objects is null.
            If x Is Nothing OrElse y Is Nothing Then Return False
    
            ' Check whether the products' properties are equal.
            Return (x.Code = y.Code) AndAlso (x.Name = y.Name)
        End Function
    
        Public Function GetHashCode1(
            ByVal product As Product
            ) As Integer Implements IEqualityComparer(Of Product).GetHashCode
    
            ' Check whether the object is null.
            If product Is Nothing Then Return 0
    
            ' Get hash code for the Name field if it is not null.
            Dim hashProductName = 
                If(product.Name Is Nothing, 0, product.Name.GetHashCode())
    
            ' Get hash code for the Code field.
            Dim hashProductCode = product.Code.GetHashCode()
    
            ' Calculate the hash code for the product.
            Return hashProductName Xor hashProductCode ' here.....................
        End Function
    End Class
    

相关问题