【发布时间】:2021-07-27 03:12:52
【问题描述】:
为了学习和理解 IL,我尝试替换对象中私有字段的值,但它不起作用。
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));
}
鉴于以下伪代码,名为_value 的私有字段不会改变:
// field = Example._value
var writer = GetWriterForField(field);
writer(ref newInstance, 100); // Example._value = 0
我不确定如何调试它,或者我的 IL 语法有什么不正确之处。我几乎在学习 IL 并从不同来源获取一些信息,试图让它发挥作用。
【问题讨论】:
-
对我帮助很大的是sharplab.io 在那里您可以查看源代码如何转换为 IL。
-
@CSharpie 感谢该工具,我不知道!比使用 ildasm 好多了。我很难找到任何可以反编译和显示 C# 和 IL 的桌面工具。 dotPeek 我想是这样,但我希望找到一个可以将 C# IL 转换为 C#/IL 的工具,这非常小众。
标签: c# reflection cil