views:

24

answers:

1

I'm n00b in IL language. In my task i have to create dynamic types inherited from System.ServiceModel.DomainServices.Client.Entity. When i am adding additional code to set method of property, i receive "operation could destabilize the runtime". Help me, please, resolve that problem.

Code from Reflector:

L_0000: nop 
L_0001: ldarg.0 
L_0002: ldstr "Field"
L_0007: ldarg.1 
L_0008: call instance void [System.ServiceModel.DomainServices.Client]System.ServiceModel.DomainServices.Client.Entity::ValidateProperty(string, object)
L_000d: nop 
L_000e: ldarg.0 
L_000f: ldarg.1 
L_0010: stfld string SEC.Client.Views.Test::_field
L_0015: ldarg.0 
L_0016: ldstr "Field"
L_001b: call instance void [System.ServiceModel.DomainServices.Client]System.ServiceModel.DomainServices.Client.Entity::RaisePropertyChanged(string)
L_0020: nop 
L_0021: ret 

My code:

  // Generate a private field
        FieldBuilder field = typeBuilder.DefineField("_" + propertyName, type,
                                                     FieldAttributes.Private);
        // Generate a public property
        PropertyBuilder property =
            typeBuilder.DefineProperty(propertyName,
                                       PropertyAttributes.None,
                                       type,
                                       new Type[] { type });

        if(attributes != null)
        {
            foreach(var attribute in attributes)
            {
                property.SetCustomAttribute(attribute);
            }
        }

        // The property set and property get methods require a special set of attributes:

        MethodAttributes GetSetAttr =
            MethodAttributes.Public |
            MethodAttributes.HideBySig;

        // Define the "get" accessor method for current private field.
        MethodBuilder currGetPropMthdBldr =
            typeBuilder.DefineMethod("get_value",
                                     GetSetAttr,
                                     type,
                                     Type.EmptyTypes);

        // Intermediate Language stuff...
        ILGenerator currGetIL = currGetPropMthdBldr.GetILGenerator();
        currGetIL.Emit(OpCodes.Ldarg_0);
        currGetIL.Emit(OpCodes.Ldfld, field);
        currGetIL.Emit(OpCodes.Ret);

        // Define the "set" accessor method for current private field.
        MethodBuilder currSetPropMthdBldr =
            typeBuilder.DefineMethod("set_value",
                                     GetSetAttr,
                                     null,
                                     new Type[] { type });

        ILGenerator currSetIL = currSetPropMthdBldr.GetILGenerator();
        currSetIL.Emit(OpCodes.Nop);
        currSetIL.Emit(OpCodes.Ldarg_0);
        currSetIL.Emit(OpCodes.Ldstr, propertyName);
        currSetIL.Emit(OpCodes.Ldarg_1);
        var m = typeof(Entity).GetMethod("ValidateProperty",
                                         BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance,
                                         null, new [] {typeof(string), typeof(object)}, null);
        currSetIL.EmitCall(OpCodes.Call, m, null);
        currSetIL.Emit(OpCodes.Nop);
        currSetIL.Emit(OpCodes.Ldarg_0);
        currSetIL.Emit(OpCodes.Ldarg_1);
        currSetIL.Emit(OpCodes.Stfld, field);
        currSetIL.Emit(OpCodes.Ldarg_0);
        currSetIL.Emit(OpCodes.Ldstr, propertyName);
        m = typeof(Entity).GetMethod("RaisePropertyChanged",
                                        BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
        currSetIL.EmitCall(OpCodes.Call, m, null);
        currSetIL.Emit(OpCodes.Nop);
        currSetIL.Emit(OpCodes.Ret);

        // Last, we must map the two methods created above to our PropertyBuilder to
        // their corresponding behaviors, "get" and "set" respectively.
        property.SetGetMethod(currGetPropMthdBldr);
        property.SetSetMethod(currSetPropMthdBldr);
A: 

After adding box instruction, all is fine.

INs
Hello,Can you post the code plz ?
Jmix90