c#属性增量方法

时间:2018-02-13 11:51:58

标签: c# reflection invoke emit

我在运行时创建动态类型,目的是从此类型创建/序列化/反序列化对象,然后绑定到网格控件。一切正常但我用数据库中的记录更新属性的方式是可悲的。我从某个地方粘贴了这个setter生成器,当通过delegate或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.

很明显我的错是错的,但我没有看到确切的问题。我甚至不介意修改setter,因为对这些属性做过的唯一事情是它们会增加

还要提前感谢任何评论我的设计不好的人

1 个答案:

答案 0 :(得分:0)

感谢您的评论。除了XY的傲慢之外,所有人都很有帮助。关于ildasm的评论是最有帮助的。我忘记了这一点,但这太棒了。几乎给了我一个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%的效率,而且相对于数据表大幅提升