Click here to Skip to main content
15,946,988 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
I am investigating using reflection methods on structures. I am able to use GetValue ok. The problem is with trying to SetValue.

The data structure I am testing this on is a member of a utility class. Here is the structure definition:

VB
' data structure
Structure RecordType
    Dim Name As String
    Dim Description As String
    Dim Type As String
    Dim Value As String
End Structure


The method I am testing is(Located in a public module):

VB
Public Sub DelimStrToStruct(ByVal iArr As String, ByRef iStruct As Object, ByVal iDelimChar As Char)

    Dim tLine() As String = iArr.Split(iDelimChar)
    Dim i As Short = 0
    Dim fields As FieldInfo() = iStruct.[GetType]().GetFields(BindingFlags.Instance Or BindingFlags.[Public])

    For Each field As FieldInfo In fields

        Try

            field.SetValue(iStruct, tLine(i))

        Catch ex As NullReferenceException
            '
        End Try

        i += 1

    Next field
End Sub


This method is intended to take a passed delimited string, split it into individual elements, and then populate the passed instance of the structure with these values.

The call to the string, located in the above mentioned utility class is:

VB
Dim trec As RecordType
DelimStrToStruct(jElem, trec, "^")



jElem is a string with fields delimited by the "^" character. It is defined elsewhere.

The problem is the SetValue method does not change the value of the fields in the structure.

How do I get this to work correctly? (FYI - "System.Reflection" is imported into the module)
Posted

1 solution

I was able to develop the solution to this problem myself. It may not be the most elegant solution, but it is fully functional.

I created a new function to return a structure (as an object):

VB
Public Function StructSetValue(ByRef iStruct As Object, ByVal iFldName As String, ByVal iValue As Object) As Object
    Dim tStruct As ValueType = iStruct
    Dim field As FieldInfo = tStruct.[GetType]().GetField(iFldName)
    Try
        field.SetValue(tStruct, iValue)
        Return tStruct
    Catch ex As NotSupportedException
        Return Nothing
    End Try
End Function


I rewrote the original method as a function that calls the above:

VB
Public Function DelimStrToStruct(ByVal iArr As String, ByRef iStruct As Object, ByVal iDelimChar As Char) As Object
    Dim tLine() As String = iArr.Split(iDelimChar)
    Dim i As Short = 0
    Dim tStruct As ValueType = iStruct
    Dim fields As FieldInfo() = tStruct.[GetType]().GetFields(BindingFlags.Instance Or BindingFlags.[Public])
    For Each field As FieldInfo In fields
        tStruct = StructSetValue(tStruct, field.Name, tLine(i))
        i += 1
    Next field
    Return tStruct
End Function



Then the call to this becomes:

VB
Dim trec As RecordType
trec = DelimStrToStruct(jElem, trec, "^")


All of this does the necessary work to "unbox" the structure.

If anyone has any commentary or suggested improvements, I would more that welcome them.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900