Recuperar datos de una lista de objetos de VB.NET
Pregunta
Estoy intentando recuperar el valor correcto de una ArrayList de objetos (.NET 1.1 Framework):
Tengo lo siguiente definido:
Public AlList As New ArrayList
Public Class ItemInfo
Public ItemNo As Int16
Public ItemType As String
Public Reports As Array
Public PDFs As Array
End Class
El código del evento form_load contiene:
Dim AnItemObj As New ItemInfo
Luego un bucle que incluye:
AnItemObj.ItemNo = AFile.RecordId
AnItemObj.ItemType = temp
AlList.Add(AnItemObj)
Entonces ahora debería tener una ArrayList de estos objetos, sin embargo, si intento recuperar los datos:
MsgBox(AlList(5).ItemNo)
Siempre obtengo el ItemNo del último valor de la lista.
¿Qué me estoy perdiendo?
Solución
Coloque el código siguiente:
Dim AnItemObj As New ItemInfo
dentro de el bucle que se suma a la lista AnItemObj.
Cuando se agrega un tipo de referencia a una lista, que está añadiendo la referencia solamente, no el valor.
Esto significa que si se agrega 10 veces la misma instancia a una lista, que se sumará 10 veces la misma referencia a la lista. Pero si después todavía tiene una referencia a este caso se pueden modificar sus propiedades y, como todas las 10 entradas en la lista de puntos a la misma referencia en la memoria, se modificarán todas las 10 entradas.
Otros consejos
Entonces, tienes:
Dim AnItemObj As New ItemInfo
For ...
AnItemObj.ItemNo = AFile.RecordId
AnItemObj.ItemType = temp
AlList.Add(AnItemObj)
Next
Lo que sucede aquí es que estás creando un solo objeto, estableciendo sus valores y agregando una referencia a él a tu lista.Luego cambiará su ItemInfo y agregará otra referencia al mismo artículo a su lista.
Necesita construir un nuevo objeto en cada bucle, de la siguiente manera:
Dim AnItemObj As ItemInfo
For ...
AnItemObj = New ItemInfo
AnItemObj.ItemNo = AFile.RecordId
AnItemObj.ItemType = temp
AlList.Add(AnItemObj)
Next
¿Va a crear una nueva instancia de iteminfo por cada incremento del bucle?
No puedo ver el código de aro completo, pero me imagino que la causa no es la creación AnItemObj a un objeto nuevo ItemInfo. Así que acaba de terminar la modificación del mismo objeto y añadiendo que el nuevo la lista (todos los elementos de la lista de puntos con el mismo objeto).
AnItemObj = New ItemInfo()
AnItemObj.ItemNo = AFile.RecordId
AnItemObj.ItemType = temp
AlList.Add(AnItemObj)