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 and that just giving it a value is working with a copy, but boxing the integer doesn't help either.
What is my mistake?
What I have tried:
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()
{
SStruct rStruct = new SStruct();
rStruct.Value = 42;
Type tStruct = typeof(SStruct);
FieldInfo fValue = tStruct.GetField("Value");
object oValue = fValue.GetValue(rStruct);
Console.WriteLine("Read Value Before Mod: {0}", oValue);
fValue.SetValue(rStruct, 21);
oValue = fValue.GetValue(rStruct);
Console.WriteLine("Read Value After Mod: {0}", oValue);
object oStruct = rStruct;
fValue.SetValue(oStruct, 21);
oValue = fValue.GetValue(rStruct);
Console.WriteLine("Read After Boxing: {0}", oValue);
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
Edit:
Unboxing as suggested by Chris Copeland seems to do the trick in C#, but why does it not work in our VB enviroment? Check it out online on
dotnetfiddle.net: C# produces 42,42,21 with this:
using System;
using System.Reflection;
public static class Test
{
public struct SStruct
{
public int Value;
}
public static void Main()
{
SStruct rStruct = new SStruct();
rStruct.Value = 42;
Type tStruct = typeof(SStruct);
FieldInfo fValue = tStruct.GetField("Value");
object oValue = fValue.GetValue(rStruct);
Console.WriteLine("Read Value Before Mod: {0}", oValue);
fValue.SetValue(rStruct, 21);
oValue = fValue.GetValue(rStruct);
Console.WriteLine("Read Value After Mod: {0}", oValue);
object boxed = (object)rStruct;
fValue.SetValue(boxed, 21);
rStruct = (SStruct)boxed;
oValue = fValue.GetValue(rStruct);
Console.WriteLine("Read After Boxing: {0}", oValue);
}
}
but 42,42,42 in VB:
Imports System
Imports System.Reflection
Public 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 = CType(rStruct, Object)
fValue.SetValue(oStruct, 21)
rStruct = CType(oStruct, SStruct)
oValue = fValue.GetValue(rStruct)
Console.WriteLine("Read After Boxing: {0}", oValue)
'It didn't change.
End Sub
End Module