Q:

Moving instances of an object class in VB

I have a parent class: CMove
I have a bunch of child classes that inherit CMove: M[Name of Move]
I have a dictionary: pMoveSet(of Stings, CMove)
The Values of the dictionary are New child classes:  e.g. pMoveSet(Key1, New MTackle)
I want to set the instance from the dictionary to an array (as CMove) that holds instances of the child classes: PossMoves(i) =  kvp.Value
I do this in a “For Each” loop over the dictionary where I check the keys to see if I want the value.  If I want the value, I set the value of the kvp equal to an element of the array.
I have a msgbox that properly displays the array position and the name of the child object directly after the child object is added to the array.
My code leaves the loop and I imagine the array should carry all the relevant child classes of CMove that I want.
A msgbox identical to the one in the “For Each” loop crashes with the error “NullReferenceException was unhandled.  Object reference not set to an instance of an object.”
It seems the instance that is created and applied to the array originally in the “For Each” loop is lost by the time the array is called again outside the loop.
How can I fix this?  I would appreciate some clarity on how to handle this. The code is below.
    Dim PossMoves() As CMove, kvp As KeyValuePair(Of String, CMove)
    ReDim PossMoves(0)

    For Each kvp In pMoveSet
        If Val(kvp.Key) < pLvl Then
            PossMoves(UBound(PossMoves)) = kvp.Value
            MsgBox(UBound(PossMoves) & vbCrLf & PossMoves(UBound(PossMoves)).Name)
            ReDim PossMoves(UBound(PossMoves) + 1) 'Will add unused element after the last possible move
        End If
    Next
    ReDim Preserve PossMoves(UBound(PossMoves) - 1) 'Removes blank value at the top of array
    MsgBox(UBound(PossMoves) & vbCrLf & PossMoves(UBound(PossMoves)).Name) 'Error on this line.

A:

The problem is that you are not preserving the array when you resize it.  Therefore, every time you resize it to add a new element to the array, it clears the array.  To fix it, simply change:
ReDim PossMoves(UBound(PossMoves) + 1)

To:
ReDim Preserve PossMoves(UBound(PossMoves) + 1)

However, I would strongly recommend that you use a List(Of CMove) instead of an array.  It will be easier to work with and more efficient as well:
Dim PossMoves As New List(Of CMove)()
For Each kvp As KeyValuePair(Of String, CMove) In pMoveSet
    If Integer.Parse(kvp.Key) < pLvl Then
        PossMoves.Add(kvp.Value)
    End If
Next

