发出代码在运行时崩溃但不在调试中,为什么

时间:2011-07-17 06:16:48

标签: reflection.emit

我有一些代码,可以从类型中构建代理。它工作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

1 个答案:

答案 0 :(得分:1)

我不确定这是否是您唯一的问题,但在发出Emit操作码时,您使用了错误的Ldc_I4_1重载。你应该这样做:

setIL.Emit(OpCodes.Ldc_I4_1)

setIL.Emit(OpCodes.Ldc_I4, 1)

第一个选项将导致IL方法体略小,因为它使用专门的操作码,而第二个选项并不特定于正在加载的数字。