0

I'm attempting to use Reflection.FieldInfo.SetValue to modify a structure's integer field value. However, it doesn't get modified.

I realize, that SetValue expects an Object, but boxing the integer doesn't help either.

What is my mistake?

Here's ready to copy and paste code in C# (further below in VB as well):

using System;
using System.Reflection;

public static class Test
{
    public struct SStruct
    {
        public int Value;
    }

    public static void Main()
    {
        // Initialize a structure record.
        SStruct rStruct = new SStruct();
        rStruct.Value = 42;

        // Reading the Value field by name:
        Type tStruct = typeof(SStruct);
        FieldInfo fValue = tStruct.GetField("Value");
        object oValue = fValue.GetValue(rStruct);
        Console.WriteLine("Read Value Before Mod: {0}", oValue);

        // Attempting to modify the Value field:
        fValue.SetValue(rStruct, 21);
        oValue = fValue.GetValue(rStruct);
        Console.WriteLine("Read Value After Mod:  {0}", oValue);
        // It didn't change.

        // SetValue is expecting an object though. Box the struct.
        object oStruct = rStruct;
        fValue.SetValue(oStruct, 21);
        oValue = fValue.GetValue(rStruct);
        Console.WriteLine("Read After Boxing:     {0}", oValue);
        // It didn't change.

        Console.Read();
    }
}

Here VB:

Imports System
Imports System.Reflection

Module Test
    Public Structure SStruct
        Public Value As Integer
    End Structure

    Public Sub Main()
        'Initialize a structure record.
        Dim rStruct As New SStruct
        rStruct.Value = 42

        'Reading the Value field by name:
        Dim tStruct As Type = GetType(SStruct)
        Dim fValue As FieldInfo = tStruct.GetField("Value")
        Dim oValue As Object = fValue.GetValue(rStruct)
        Console.WriteLine("Read Value Before Mod: {0}", oValue)

        'Attempting to modify the Value field:
        fValue.SetValue(rStruct, 21)
        oValue = fValue.GetValue(rStruct)
        Console.WriteLine("Read Value After Mod:  {0}", oValue)
        'It didn't change.

        'SetValue is expecting an object though. Box the struct.
        Dim oStruct As Object = rStruct
        fValue.SetValue(oStruct, 21)
        oValue = fValue.GetValue(rStruct)
        Console.WriteLine("Read After Boxing:     {0}", oValue)
        'It didn't change.

        Console.Read()
    End Sub
End Module
  • 1
    Change `SStruct` to a class instead of a structure. Does it work as you expect? You need to learn the difference between reference types and value types. – jmcilhinney Feb 25 '21 at 08:26
  • In general, this sort of thing doesn't work. The value you're modifying is a boxed _copy_ of the original value you actually want to modify. See https://stackoverflow.com/questions/5057267/what-is-the-difference-between-a-reference-type-and-value-type-in-c. If you want to get really messy, see duplicate for the approach that can work. IMHO, if you don't already have a fully innate understanding of why this didn't work in the first place, it's probably better to not be using reflection to modify your object values at all. Use more conventional means, feel free to ask questions if you need help. – Peter Duniho Feb 25 '21 at 08:38

0 Answers0