Imagine we have a mutable struct
(yes, don't start):
public struct MutableStruct
{
public int Foo { get; set; }
public override string ToString()
{
return Foo.ToString();
}
}
Using reflection, we can take a boxed instance of this struct
and mutate it inside the box:
// this is basically what we want to emulate
object obj = new MutableStruct { Foo = 123 };
obj.GetType().GetProperty("Foo").SetValue(obj, 456);
System.Console.WriteLine(obj); // "456"
What I would like to do is to write some IL that can do the same as this - but faster. I'm a meta-programming junkie ;p
It is trivial to unbox-any the value and mutate the value using regular IL - but you can't just call box it afterwards because that will create a different box. I'm guessing that what we would need to do here is copy it over the existing box. I have investigated ldobj
/ stobj
, but those don't seem to do the job (unless I'm missing something).
So: does a mechanism to do this exist? Or must I limit myself to reflection to perform in-place updates of boxed struct
s ?
Or in other words: what ... evil goes here...
?
var method = new DynamicMethod("evil", null,
new[] { typeof(object), typeof(object) });
var il = method.GetILGenerator();
// ... evil goes here...
il.Emit(OpCodes.Ret);
Action<object, object> action = (Action<object, object>)
method.CreateDelegate(typeof(Action<object, object>));
action(obj, 789);
System.Console.WriteLine(obj); // "789"
SetValue
code into a new method and pass the boxed value in and still mutate the value of the original struct. Boxing it and then using reflection does seem to indicate that the struct itself is passed by reference. Interesting. – Finlandobject
- so it is boxed immediately. – Benco