In my effort to learn and understand IL I'm trying to replace the value of a private field in an object, however it's not working.
public class Example
{
private int _value;
}
private delegate void _memberUpdaterByRef(ref object source, object value);
private _memberUpdaterByRef GetWriterForField(FieldInfo field)
{
// dynamically generate a new method that will emit IL to set a field value
var type = field.DeclaringType;
var dynamicMethod = new DynamicMethod(
$"Set{field.Name}",
typeof(void),
new Type[] { typeof(object).MakeByRefType(), typeof(object) },
type.Module,
true
);
var gen = dynamicMethod.GetILGenerator();
var typedSource = gen.DeclareLocal(field.DeclaringType);
gen.Emit(OpCodes.Ldarg_0); // Load the instance of the object (argument 0) onto the stack
gen.Emit(OpCodes.Ldind_Ref); // load as a reference type
gen.Emit(OpCodes.Unbox_Any, field.DeclaringType);
gen.Emit(OpCodes.Stloc_0); // pop typed arg0 into temp
gen.Emit(OpCodes.Ldloca_S, typedSource);
gen.Emit(OpCodes.Ldarg_1); // Load the instance of the object (argument 1) onto the stack
gen.Emit(OpCodes.Unbox_Any, field.FieldType);
gen.Emit(OpCodes.Stfld, field);
gen.Emit(OpCodes.Ldarg_0); // Load the instance of the object (argument 0) onto the stack
gen.Emit(OpCodes.Ldloc_0); // push temp
gen.Emit(OpCodes.Box, field.DeclaringType);
gen.Emit(OpCodes.Stind_Ref); // store object reference
gen.Emit(OpCodes.Ret); // return void
// create a delegate matching the parameter types
return (_memberUpdaterByRef)dynamicMethod.CreateDelegate(typeof(_memberUpdaterByRef));
}
Given the following pseudo-code, the private field named _value
does not change:
// field = Example._value
var writer = GetWriterForField(field);
writer(ref newInstance, 100); // Example._value = 0
I'm not really sure how to debug this, or what is incorrect about my IL syntax. I'm pretty much learning IL and grabbing bits from different sources trying to get this to work.
Aucun commentaire:
Enregistrer un commentaire