我有一些代码,可以从类型中构建代理。它工作perfekt。 然后我添加了setter emit代码,它在调用时必须按下一个isDirty位。这失败了,为什么?
如果我运行没有isDirty位的代码,它可以工作。 如果我使用isDirty位运行代码,它在调试中工作,但是在visual studio中启动反汇编窗口。 如果我使用isDirty运行代码(没有调试)程序崩溃(没有响应)但是当我点击取消时,它开始工作并显示所有数据。
PropertyBuilder property = proxy.DefineProperty(propertyInfo.Name, propertyInfo.Attributes, propertyInfo.PropertyType, null);
MethodAttributes attributes = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.Virtual;
MethodBuilder setMethod = proxy.DefineMethod("set_" + propertyInfo.Name, attributes, typeof(void), new Type[] { propertyInfo.PropertyType });
ILGenerator setIL = setMethod.GetILGenerator();
setIL.Emit(OpCodes.Ldarg_0); // load this on the stack - where this is the type we are creating
setIL.Emit(OpCodes.Ldarg_1); // load first parameter on the stack
setIL.Emit(OpCodes.Call, propertyInfo.GetSetMethod());
{
//error here: when this is uncomment, it fails
// // set the isDirty bit
// setIL.Emit(OpCodes.Ldarg_0); // load this on the stack
// setIL.Emit(OpCodes.Ldc_I4_1, 1); // push a number on the stack
// setIL.Emit(OpCodes.Stfld, isDirtyField); // save the value on the stack in field
}
setIL.Emit(OpCodes.Ret);
property.SetSetMethod(setMethod);
我很难过,看到为什么会失败?需要专家的帮助:))
// dennis
答案 0 :(得分:1)
我不确定这是否是您唯一的问题,但在发出Emit
操作码时,您使用了错误的Ldc_I4_1
重载。你应该这样做:
setIL.Emit(OpCodes.Ldc_I4_1)
或
setIL.Emit(OpCodes.Ldc_I4, 1)
第一个选项将导致IL方法体略小,因为它使用专门的操作码,而第二个选项并不特定于正在加载的数字。