我想使用Dictionary(Of Key,Value),Key不是基类型,而是类:
Public Class MyKey
Sub New(ByVal packet As String, ByVal sent As Boolean)
Me.packet = packet.ToUpper.Trim
Me.sent = sent
End Sub
Private packet As String
Private sent As Boolean
End Class
现在要让Dictionary工作并找到键,我必须在Key类中实现System.IEquatable接口(或使用不同的构造函数,但这是另一个故事):
Public Class MyKey
Implements System.IEquatable(Of MyKey)
Sub New(ByVal packet As String, ByVal sent As Boolean)
Me.packet = packet.ToUpper.Trim
Me.sent = sent
End Sub
Public Overloads Function Equals(ByVal other As MyKey) As Boolean Implements IEquatable(Of MyKey).Equals
Return other.sent = Me.sent AndAlso other.packet = Me.packet
End Function
Private packet As String
Private sent As Boolean
End Class
但是要获得一致的结果,我还要实现Object.Equals和Object.GetHashCode:
Public Class MyKey
Implements System.IEquatable(Of MyKey)
Sub New(ByVal packet As String, ByVal sent As Boolean)
Me.packet = packet.ToUpper.Trim
Me.sent = sent
End Sub
Public Overloads Function Equals(ByVal other As ChiavePietanza) As Boolean Implements IEquatable(Of MyKey).Equals
Return other.sent = Me.sent AndAlso other.packet = Me.packet
End Function
Overrides Function Equals(ByVal o As Object) As Boolean
Dim cast As MyKey = DirectCast(o, MyKey)
Return Equals(cast)
End Function
Public Overrides Function GetHashCode() As Integer
Return packet.GetHashCode Or sent.GetHashCode
End Function
Private packet As String
Private sent As Boolean
End Class
问题是:GetHashCode实现是否正确?我应该如何实现它,返回一个哈希码,它将字符串和布尔哈希码合并?
答案 0 :(得分:4)
您的GetHashCode函数是正确的,并且符合已知的哈希代码实现规则。特别是
MyKey
MyKey
虽然可以做得更好的一种方法是让packet
和sent
成为ReadOnly
字段。现在暗示它们是ReadOnly
因为它们在GetHashCode函数中使用。但是,未来的开发人员可能会忽略这一点,改变值并破坏GetHashCode所需的合同。明确地ReadOnly
使用它们可以防止意外中断。
另一个小调。虽然为IEquatable(Of T)
密钥实施Dictionary
是个好主意,但这不是必需的。所需要的只是覆盖Equals
和GetHashCode
方法,以使密钥在Dictionary
中正常运行。
答案 1 :(得分:2)
它很好,但是Or运算符不会生成分布均匀的哈希值,因为它只能打开位而不能关闭。请改用Xor运算符。
答案 2 :(得分:2)
本文是我所有GetHashCode
覆盖的基础:
SO - What is the best algorithm for an overridden System.Object.GetHashCode? 所以你可以这样做:
public override int GetHashCode() {
int hash = 17;
hash = (hash * 23) + ((packet != null) ? packet.GetHashCode() : 0);
hash = (hash * 23) + ((sent != null) ? sent.GetHashCode() : 0);
return hash;
}
应该直接将其移植到VB。
答案 3 :(得分:0)
如果你想要一些简单的东西,并且表现并不重要,我相信结构类型的字典会将两个结构视为相同,如果它们的所有成员都相等。性能不是很好,但代码非常简单。