A HashTable can be used to store a collection of key/value pairs. The key object is used to uniquely identify the key/value pair which makes is easy to store data like a database.
The type of the key object which is added to the HashTable is variable. It can be an integer, a string, a GUID etc. Because of the nature of a GUID (a globally unique identifier) it is an ideal candidate for a key object.
If you want to use a combination of two (or more) GUIDS as a key object you can create a class object, but there is a caveat.
Example #1 – How you shouldn’t use it
Let’s take create two GUID objects, called objKey1 and objKey2, and fill them with a GUID.
Dim objKey1 As Guid = New Guid("423baa7b-4f46-4b42-b3e8-498e11099544")
Dim objKey2 As Guid = New Guid("f0bcf839-4349-4ff2-8695-6a91df86cabb")
Now where going to create a hashtable called objHashTable where the key/value pairs are stored.
Dim objHashTable As New Hashtable()
Because we want to store two GUID’s as a key object where going to create a simple class called ValueKey.
Private Class ValueKey
Public Key1 As Guid
Public Key2 As Guid
Public Sub New(Key1ID As Guid, Key2ID As Guid)
Key1 = Key1ID
Key2 = Key2ID
End Sub
End Class
Now let’s add a key/value pair to the hashable
objHashTable.Add(objKey, Date.Now)
The hashtable objHashTable now contains one key/value pair. We can check if the key object we’ve just added is in the hashtable:
Debug.Print("Key found #1 : " & objHashTable.ContainsKey(objKey))
Key found #1 : True
Okay, as expected. Now let’s create a new object key with exact the same content (objKey1 and objKey2)
objKey = New ValueKey(objKey1, objKey2)
Since the content of the key is exactly the same (objKey1 and objKey2 isn’t changed) you expect the key to be present in the hashtable:
Debug.Print("Key found #2 : " & objHashTable.ContainsKey(objKey))
Key found #1 : False
That was NOT the expected result. Although the content of the key object is equal, the hashtable can’t find the key object.
Example #2 – How you should use it
The problem in example 1 is caused by the uniqueness of the KeyValue class. If you compare the two objects with Object.Equals method you’ll notice they are not equal. If the objects are not equal, the key value in the hashtable will never match.
The solution lies in the KeyValue class, it needs an override for the Equals (and GetHashCode) method.
So let’s use the same code as in example 1 but add an override for the Equals and GetHashCode in the KeyValue class.
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Dim objKey1 As Guid = New Guid("423baa7b-4f46-4b42-b3e8-498e11099544")
Dim objKey2 As Guid = New Guid("f0bcf839-4349-4ff2-8695-6a91df86cabb")
Dim objHashTable As New Hashtable()
Dim objKey As New ValueKey(objKey1, objKey2)
objHashTable.Add(objKey, Date.Now)
Debug.Print("Key found #1 : " & objHashTable.ContainsKey(objKey))
objKey = New ValueKey(objKey1, objKey2)
Debug.Print("Key found #2 : " & objHashTable.ContainsKey(objKey))
End
End Sub
Private Class ValueKey
Public Key1 As Guid
Public Key2 As Guid
Public Sub New(Key1ID As Guid, Key2ID As Guid)
Key1 = Key1ID
Key2 = Key2ID
End Sub
Public Overrides Function Equals(ByVal obj As Object) As Boolean
If obj Is Nothing OrElse Not [GetType]().Equals(obj.GetType()) Then Return False
Return (Key1.Equals(obj.Key1)) And (Key2.Equals(obj.Key2))
End Function
Public Overrides Function GetHashCode() As Integer
Return (BitConverter.ToInt32(Key1.ToByteArray, 0) / 2) + (BitConverter.ToInt32(Key2.ToByteArray, 0) / 2)
End Function
End Class
Key found #1 : True
Key found #2 : True