I want to create a dictionary of products where the id is key and the product parameters are custom class that contain the information about the products. It seems like I am storing the information correctly, but obviously I am not, because I can retrieve only the last record. What am I doing wrong?
Public Class ProductClass
Public id As Integer
Public name As String
Public details As String
End Class
Sub Test
Dim i As Integer
Dim singleProduct As New ProductClass
Dim testDb As New Dictionary(Of Integer, ProductClass)
For i = 1 To 3
singleProduct.id = i
singleProduct.name = "Product " & i
singleProduct.details = "blablabla"
testDb.Add(singleProduct.id, singleProduct)
Next i
For Each dbKey As Integer In testDb.Keys
Debug.Print(dbKey & " :: " & testDb(dbKey).name & vbCrLf)
Next
End Sub
The debug output:
1 :: Product 3
2 :: Product 3
3 :: Product 3
The problem is that you are only creating one instance of singleProduct, outside of the loop. Inside the loop, you overwrite this instances properties on every pass, and store the same instance in the map every time.
That is because "ProductClass" is an object-type. Objects are not copied when you pass them to a function, but instead given a reference to that instance. "Integer" on the other hand is not an object, so the map-key get copied every time. Thus, you will end up of a map of 3 entries, each pointing to the same "singleProduct".
The solution is simple. Move the line where you create "singleProduct" inside the loop. That way, you will add 3 individual instances into the map. I don't know VB.net very will, but most languages have the concept of "constructor arguments", which would help you avoid such errors by forcing you to pass the properties directly to the instance-construction, instead of setting them manually on the existing instance. You should try to see if VB supports it and use it for those cases.