重写 GetHashCode 变体
我有一个理论类 Name_Order,它有一个字符串 Name
和一个 int Order
。
我需要指出,如果 NameOrder 对不同,即名称或顺序不同,则两个 Name_Order
是不同的。
现在,覆盖 Equals 没有问题,但我对 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
得到的结果相同...
另一种覆盖那个方法?
I have a theoretical class Name_Order, that has a string Name
and a int Order
.
I need to indicate that two Name_Order
's are different, if the pair NameOrder is different, that is, or name or order are different.
Now, overriding Equals no problemo, but I have some "issues" with 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
In that case, summing the hashcodes, leave a (small, but real) possibility that two distinct Name_Orders with different names or orders be "identical".
Say, adding the 7
+ 154
gives the same result as adding 154
+ 7
...
An alternative override of that method?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
首先,虽然避免碰撞固然很好,但如果发生碰撞也不是问题。但常见的方法是这样的:
这在例如点/位置中更为明显,最好避免明显的对角线碰撞,例如 (2,3) 与 (3,2)。
代码中的一个更大问题是 hash/equals 中的属性是可变的;如果它们发生变化,字典等中的任何用法都将停止工作。您应该更喜欢只读键值。
Firstly, while avoiding collisions is good, it isn't a problem if there are collisions. But a common approach is something like:
This is more noticeable in, for example, a point/position, where it would be nice to avoid obvious diagonal collisions like (2,3) vs (3,2).
A much bigger problem in your code is that the properties in the hash/equals are mutable; if they get changed, any usage in dictionaries etc will stop working. You should prefer read-only key values.
MSDN 在这里给出了该情况的答案的变体(在示例部分):
http ://msdn.microsoft.com/en-us/library/bb338049.aspx
MSDN gives its variant of the answer for that case here (in the Example's section):
http://msdn.microsoft.com/en-us/library/bb338049.aspx