Setting an attribute of a structure using Reflection RRS feed

  • Question

  • Hi,

    I have some inherited VB6 code that makes use of a large set of Structures to read data from 'binary' files.

    I am trying to use reflection 

    Sub ReadBinaryFile(recordTypeStructureInstance as Object)

       Dim objectType as Type = recordTypeStructureInstance.GetType()

       For each elementInStructure as System.Reflection.FieldInfo in objectType.GetFields()


            ' Work out size / type of field e.g.  Fixed length string (20 ASCII character) and read from file using BinaryReader


          stringRead = System.Text.Encoding.ASCII.GetString(fileBuffer)


        // Everything all good to this point, i.e. I have used reflection to determine that the structure contains a fixed length string.

        //  I have read string (ASCII) from file and created a VB String.

        // However when I try and Set the value of the field, statement


          objectType.GetField(elementInStructure.Name).SetValue(recordTypeStructureInstance, stringRead.toCharArray)


     // The statement executes without throwing an exception, however the field  "elementInStructure.Name)" in the object recordTypeStructureInstance is not updated.

    I have tried various ways of doing this, and am obviously missing something obvious.

    Any help would be much appreciated.

    Tuesday, July 11, 2017 6:10 PM

All replies

  • There is plenty of posts about this problem.  You would have to do some of the boxing that does for you.  I would turf all the vb6 code.  Trying to emulate vb6 is a really bad idea with lots of problems.  

    I have tried without boxing and get the same problem with reflection.  Also setting a string with toCharArray should give problems anyway as a char array is not a string.

    Lloyd Sheen

    Tuesday, July 11, 2017 6:38 PM
  • The following code works.

    The structure definition:

    Public Structure RecordType
        Dim Name As String
        Dim Description As String
        Dim Type As String
        Dim Value As String
    End Structure


        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)
                field.SetValue(tStruct, iValue)
                Return tStruct
            Catch ex As NotSupportedException
                Return Nothing
            End Try
        End Function
        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

    Sample use:

            ' A string with all fields of the structure
            ' delimitted by ^
            Dim jElem As String = "Name^Description^Type^Value"
            Dim trec As RecordType
            trec = DelimStrToStruct(jElem, trec, "^")

    All fields are initialized correctly using this code (tested).  The key to this is using the structure as ValueType

    Lloyd Sheen

    • Edited by sqlguy Tuesday, July 11, 2017 8:30 PM
    Tuesday, July 11, 2017 8:29 PM
  •  // The statement executes without throwing an exception, however the field  "elementInStructure.Name)" in the object recordTypeStructureInstance is not updated.

    That invariably indicates that you are not updating the object instance that you think you are updating. See, for instance:

    Tuesday, July 11, 2017 10:55 PM