c#属性增量法
我在运行时创建一个动态类型,目的是从该类型创建/序列化/反序列化对象,然后绑定到网格控件。一切都正常,但我用数据库中的记录更新属性的方法很可怜。我从某处粘贴了这个setter生成器,当通过委托或PropertyInfo(…)调用它时,它工作得非常好 但当我试图厚着脸皮,制作自己的版本时,它会增加而不是设置c#属性增量法,c#,reflection,invoke,emit,C#,Reflection,Invoke,Emit,我在运行时创建一个动态类型,目的是从该类型创建/序列化/反序列化对象,然后绑定到网格控件。一切都正常,但我用数据库中的记录更新属性的方法很可怜。我从某处粘贴了这个setter生成器,当通过委托或PropertyInfo(…)调用它时,它工作得非常好 但当我试图厚着脸皮,制作自己的版本时,它会增加而不是设置 ILGenerator incIl = incMethodBuilder.GetILGenerator(); incIl.Emit(OpCodes.Ldarg_0); //add objec
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是错误的,但我没有看到确切的问题。我甚至不介意修改setter,因为对这些属性所做的唯一一件事就是它们是递增的
还要提前感谢任何评论我的设计不好的人谢谢你的评论。除了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);
调用的最佳结果是按照本指南进行的,其中一条注释是copy/paste gold。我正在缓存代表
private Dictionary<Int32, DynamicMethodDelegate> valueDeltas;
总体而言,my方法的效率仍远未达到100%,它比datatables有了巨大的改进您能告诉我们为什么您认为在运行时需要动态类型吗?以防万一这是XY问题
OpCodes.Stfld
需要引用对象来存储非静态字段,但您使用的是OpCodes.Ldfld
。从第一段代码可以看出,Stfld
有两个操作数。在代码的堆栈上只剩下一个。您需要一个额外的ldarg.0
。请注意:尝试用c#/vb编写代码,然后使用visual studio中的适当工具或使用反编译器/ildasm查看生成的IL。然后,你可以在你的动态类型中复制必要的IL。如果你有一个完整的答案,不要只写在注释中。把它放在那个可爱的答题箱里。评论对于要求澄清,甚至只是建议OP思考的事情来说都是很好的,但是当你告诉他们如何解决问题时,答案框是解决问题的地方,而不是评论框。
private Dictionary<Int32, DynamicMethodDelegate> valueDeltas;
foreach (var kvp in result)
{
valueDeltas[kvp.Key](rowData, kvp.Value[0]);
sampleDeltas[kvp.Key](rowData, kvp.Value[1]); //...