【发布时间】:2014-09-02 19:55:17
【问题描述】:
如何使用 DynamicMethod 通过反射将值设置为结构字段 - myStruct.myField?当我调用setter(myStruct, 111) 时,没有设置值,因为MyStruct 是值类型。 Console.WriteLine(myStruct.myField) 显示值 3。
如何修改GetDelegate方法将值设置为myStruct.myField?
public struct MyStruct
{
public int myField;
}
public delegate void SetHandler(object source, object value);
private static SetHandler GetDelegate(Type type, FieldInfo fieldInfo)
{
DynamicMethod dm = new DynamicMethod("setter", typeof(void), new Type[] { typeof(object), typeof(object) }, type, true);
ILGenerator setGenerator = dm.GetILGenerator();
setGenerator.Emit(OpCodes.Ldarg_0);
setGenerator.DeclareLocal(type);
setGenerator.Emit(OpCodes.Unbox_Any, type);
setGenerator.Emit(OpCodes.Stloc_0);
setGenerator.Emit(OpCodes.Ldloca_S, 0);
setGenerator.Emit(OpCodes.Ldarg_1);
setGenerator.Emit(OpCodes.Unbox_Any, fieldInfo.FieldType);
setGenerator.Emit(OpCodes.Stfld, fieldInfo);
setGenerator.Emit(OpCodes.Ldloc, 0);
setGenerator.Emit(OpCodes.Box, type);
setGenerator.Emit(OpCodes.Ret);
return (SetHandler)dm.CreateDelegate(typeof(SetHandler));
}
MyStruct myStruct = new MyStruct();
myStruct.myField = 3;
FieldInfo fi = typeof(MyStruct).GetField("myField", BindingFlags.Public | BindingFlags.Instance);
SetHandler setter = GetDelegate(typeof(MyStruct), fi);
setter(myStruct, 111);
Console.WriteLine(myStruct.myField);
【问题讨论】:
-
这就是我们不使用可变结构的原因。你正在改变结构的副本。创建一个新版本的结构,其中的字段已初始化为您想要的。
-
相关set a field of struct 问题可能是你所追求的......旁注:很好的问题和很好的样本......但你想要实现的整个目标是非常令人困惑,在大多数情况下不太可能按照您想要的方式工作......
-
糟糕;我意识到我搞砸了我的答案;已编辑 - 但是,作为
ref MyStruct会更好
标签: c# reflection struct reflection.emit