Question

This question is a follow-on to VB ReDim of member field programmatically. After the arrays are dimensioned appropriately, I try to set the values of the elements, but I get an exception at run time when I try to assign the first value (MySB.AssignValues(0, "B", 0, 7.6))

System.InvalidCastException was unhandled
HResult=-2147467262
Message=Object cannot be stored in an array of this type.
Source=mscorlib

Module TestSetArray

    Public Class BS
        Public A As String
        Public B() As Double
        Public C() As Double

    End Class

    Public Class SB

        Public MyBS() As BS

        'ReadFieldString is a function that returns a string of the field name of Class BS,
        'i.e., A, B or C.  For test purpose, retun a constant
        Public Function ReadFieldString() As String
            Return "B"
        End Function

        'GetArrayDim is a function that returns an integer, which is the size of the array
        'of that field name. For test purpose, retun a constant
        Public Function GetArrayDim() As Integer
            Return 2
        End Function

        Public Sub DimArrays()
            ReDim MyBS(3)
            Dim i As Integer
            For i = 0 To MyBS.Length - 1
                MyBS(i) = New BS()
                Dim f = GetType(BS).GetField(ReadFieldString())
                f.SetValue(MyBS(i), Array.CreateInstance(f.FieldType.GetElementType(), GetArrayDim()))
            Next
        End Sub

        Public Sub AssignValues(MainIndex As Integer, TheName As String, TheIndex As Integer, TheValue As Double)
            Dim f = MyBS(MainIndex).GetType.GetMember(TheName)
            f.SetValue(TheValue, TheIndex)
        End Sub

    End Class

    Sub Main()
        Dim MySB As SB = New SB
        MySB.DimArrays()
        MySB.AssignValues(0, "B", 0, 7.6)
        MySB.AssignValues(0, "B", 1, 8.2)
    End Sub

End Module

Thanks in advance.

Was it helpful?

Solution

The problem is that the GetMember method returns an array of type MemberInfo, not the double array of the class. You'd probably have an easier time if you used GetField instead. You have to call GetValue and cast its result to an Array in order to use SetValue to set the value.

Public Sub AssignValues(MainIndex As Integer, TheName As String, TheIndex As Integer, TheValue As Double)
    Dim f = MyBS(MainIndex).GetType().GetField(TheName)
    Dim doubleArray = DirectCast(f.GetValue(MyBS(MainIndex)), Array)
    doubleArray.SetValue(TheValue, TheIndex)
End Sub

or if you know that the array will always be an array of Double, you can cast it directly to that:

Public Sub AssignValues(MainIndex As Integer, TheName As String, TheIndex As Integer, TheValue As Double)
    Dim f = MyBS(MainIndex).GetType().GetField(TheName)
    Dim doubleArray = DirectCast(f.GetValue(MyBS(MainIndex)), Double())
    doubleArray(TheIndex) = TheValue
End Sub
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top