ABL - The Problem Solver - .Net FAQ
 

Home
Mission
News
Blog
Tools
FAQ
Publications
Downloads
Contact
Contents

 

Frequently asked questions

.NET FAQ Visual FoxPro FAQ

 


Reflection and Structures

Some time ago I wrote some code so set object properties/fields at runtime by reading an XML config file. The code was quite straightforward using reflection and all seemed well until someone decided to add a structure and tried to set the structures fields. This failed because a structure is a reference type an therefore its contents are copied when passed as a ByVal parameter. However after changing the parameters to ByRef the code still didn’t work as the final call to FieldInfo.SetValue() was out of my reach as it is part of the .Net framework. Some research on the web showed I wasn’t the first to run into this problem but no one seemed to have a solution as far as I could determine. Some further investigation did result in a fix though. If you cast passed to structure to a variable of type ValueType and used that instead of a generic type Object Old code (doesn’t work for the structure):

Module Module1
    Sub Main()
        Dim tc As New TestClass
        Dim ts As TestStructure

        ' Using an object
        tc.Name = "Maurice in an object"
        Console.WriteLine(tc.Name)
        ChangeName(tc)
        Console.WriteLine(tc.Name)

        ' Using a structure
        ts.Name = "Maurice in a structure"
        Console.WriteLine(ts.Name)
        ChangeName(ts)
        Console.WriteLine(ts.Name)

        Console.ReadLine()
    End Sub

    Sub ChangeName(ByRef var As Object)
        Dim t As Type
        Dim fi As Reflection.FieldInfo
        t = var.GetType()
        fi = t.GetField("Name")
        fi.SetValue(var, "Maurice de Beijer")
    End Sub
End Module

Structure TestStructure
    Public Name As String
End Structure

Class TestClass
    Public Name As String
End Class

New code:
    Sub ChangeName(ByRef var As Object)
        Dim vt As ValueType
        Dim t As Type
        Dim fi As Reflection.FieldInfo

        t = var.GetType()
        fi = t.GetField("Name")

        If t.IsValueType Then
            vt = var
           
fi.SetValue(vt, "Maurice de Beijer")
       
Else
            fi.SetValue(var, "Maurice de Beijer")
        End If
    End Sub

Interestingly creating an overloaded ChangeName function with a parameter typed as ValueType doesn’t work, the function with Object will still be called with the structure.

 


 

Send mail to webmaster@TheProblemSolver.nl with questions or comments about this web site.
Copyright © 1995 - 2007 ABL - The Problem Solver
Last modified: 10/21/06
WF
RSS 2.0