我在运行时创建动态类型,目的是从此类型创建/序列化/挑选对象,然后绑定到网格控件。一切都起作用,但我使用数据库记录更新属性的方式是可悲的。我从某个地方粘贴了这个设置器生成器,当通过委托或propertyinfo(...(。setValue(...(
调用时,它可以很好地工作。ILGenerator setIl = setPropMthdBldr.GetILGenerator();
Label modifyProperty = setIl.DefineLabel();
Label exitSet = setIl.DefineLabel();
setIl.MarkLabel(modifyProperty);
setIl.Emit(OpCodes.Ldarg_0);
setIl.Emit(OpCodes.Ldarg_1);
setIl.Emit(OpCodes.Stfld, fieldBuilder);
setIl.Emit(OpCodes.Nop);
setIl.MarkLabel(exitSet);
setIl.Emit(OpCodes.Ret);
propertyBuilder.SetSetMethod(setPropMthdBldr);
但是,当我尝试厚脸皮并制作自己的版本时,可以增加而不是设置
ILGenerator incIl = incMethodBuilder.GetILGenerator();
incIl.Emit(OpCodes.Ldarg_0); //add object to stack
incIl.Emit(OpCodes.Ldfld, fieldBuilder); //add current field value to stack
incIl.Emit(OpCodes.Ldarg_1); //add method parameter to stack
incIl.Emit(OpCodes.Add); //combine last 2 items
incIl.Emit(OpCodes.Stfld, fieldBuilder); //write added value back
incIl.Emit(OpCodes.Nop); //no clue
incIl.Emit(OpCodes.Ret);
当我尝试通过代表或什至getMethod(...(。调用(...(时,我会得到同样的失败
Common Language Runtime detected an invalid program.
很明显我的IL是错误的,但我没有看到确切的问题。我什至不介意将设置器修改为这些属性唯一做的事情是它们会增加
也要事先感谢任何评论我的设计不好的人
感谢您的评论。除了XY傲慢以外,所有人都很有帮助。关于Ildasm是最有帮助的评论。我忘记了这一点,但太棒了。几乎给了我一个小说。
MethodBuilder incPropMthdBldr =
tb.DefineMethod("_Inc" + propertyName,
MethodAttributes.Public ,
null, new[] { propertyType });
incPropMthdBldr.DefineParameter(0, ParameterAttributes.In, "increaseBy");
ILGenerator incIl = incPropMthdBldr.GetILGenerator();
incIl.Emit(OpCodes.Nop);
incIl.Emit(OpCodes.Ldarg_0);
incIl.Emit(OpCodes.Ldarg_0);
incIl.Emit(OpCodes.Ldfld, fieldBuilder);
incIl.Emit(OpCodes.Ldarg_1);
incIl.Emit(OpCodes.Add);
incIl.Emit(OpCodes.Stfld, fieldBuilder);
incIl.Emit(OpCodes.Ret);
最好的结果是通过遵循本指南https://www.codeproject.com/articles/10951/webcontrols/其中的注释之一来完成。我正在缓存代表
private Dictionary<Int32, DynamicMethodDelegate> valueDeltas;
然后,当我的变换块登陆方格标志
时foreach (var kvp in result)
{
valueDeltas[kvp.Key](rowData, kvp.Value[0]);
sampleDeltas[kvp.Key](rowData, kvp.Value[1]); //...
总体而言,我的方法仍然远远不到100%效率,它大大改善了数据级