c# property incrementer 方法

标签 c# reflection invoke emit

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

当我尝试通过委托(delegate)甚至 GetMethod(...).Invoke(...) 调用这个坏男孩时,我遇到了同样的失败

Common Language Runtime detected an invalid program.

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

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

最佳答案

感谢您的评论。除了 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;

然后当我的变换 block 碰到方格旗时

foreach (var kvp in result)
        {               
            valueDeltas[kvp.Key](rowData, kvp.Value[0]);
            sampleDeltas[kvp.Key](rowData, kvp.Value[1]); //...

总的来说,我的方法仍然远未达到 100% 的效率,它比数据表有了很大的改进

关于c# property incrementer 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48766217/

相关文章:

c# - Automapper基类映射

c# - 服务定位器困惑

java - 在java中迭代声明的数组列表

c# - 如何在没有任何参数和任何返回值的情况下通过反射调用某些方法?

c# - ASP.NET Core appsettings.json 未加载正确的设置

c# - 这怎么不会在Silverlight中引起跨线程异常?

java - 获取类简单名称(包括包装类!)

c++ - Boost Fusion 调用和 SFINAE

c# - 如何使用 C#/.NET 的反射在程序集中实例化类?

sql - 如何从一个 cfc 文件中的函数查询中调用另一个 CFC 文件中的函数?