c#属性增量法

c#属性增量法,c#,reflection,invoke,emit,C#,Reflection,Invoke,Emit,我在运行时创建一个动态类型,目的是从该类型创建/序列化/反序列化对象,然后绑定到网格控件。一切都正常,但我用数据库中的记录更新属性的方法很可怜。我从某处粘贴了这个setter生成器,当通过委托或PropertyInfo(…)调用它时,它工作得非常好 但当我试图厚着脸皮,制作自己的版本时,它会增加而不是设置 ILGenerator incIl = incMethodBuilder.GetILGenerator(); incIl.Emit(OpCodes.Ldarg_0); //add objec

我在运行时创建一个动态类型,目的是从该类型创建/序列化/反序列化对象,然后绑定到网格控件。一切都正常,但我用数据库中的记录更新属性的方法很可怜。我从某处粘贴了这个setter生成器,当通过委托或PropertyInfo(…)调用它时,它工作得非常好

但当我试图厚着脸皮,制作自己的版本时,它会增加而不是设置

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]); //...