Exemple #1
0
        private static void ImplementGetInspector(PropertyBuilderContext context, Action <PropertyBuilderContext> implement, MethodInfo getInspector)
        {
            // Run real implementor first
            implement(context);

            // Getter now has value to be returned as single element on stack
            if (context.GetMethodGenerator != null)
            {
                // Store return value in local var
                LocalBuilder returnValue = context.GetMethodGenerator.DeclareLocal(context.Property.PropertyType);
                context.GetMethodGenerator.Emit(OpCodes.Stloc, returnValue);

                // Call inspector(layer, PropertyInfo, value)
                context.GetMethodGenerator.Emit(OpCodes.Ldarg_0);
                context.GetMethodGenerator.Emit(OpCodes.Ldsfld, context.PropertyInfoField);
                context.GetMethodGenerator.Emit(OpCodes.Ldloc, returnValue);
                if (context.Property.PropertyType.IsValueType)
                {
                    context.GetMethodGenerator.Emit(OpCodes.Box, context.Property.PropertyType);
                }

                // Allow inspector be generic in property type
                getInspector = getInspector.Specialize(context.BaseClass, typeof(void), typeof(PropertyInfo), context.Property.PropertyType);

                context.GetMethodGenerator.EmitCall(OpCodes.Call, getInspector, null);

                // Load real return value to leave stack unchanged
                context.GetMethodGenerator.Emit(OpCodes.Ldloc, returnValue);
            }
        }
Exemple #2
0
        /// <summary>
        /// Implements properties using getter and setter methods
        /// </summary>
        /// <param name="context"></param>
        /// <param name="initMethod"></param>
        /// <param name="getMethod"></param>
        /// <param name="setMethod"></param>
        private static void ImplementGetterAndSetter(PropertyBuilderContext context, MethodInfo initMethod, MethodInfo getMethod, MethodInfo setMethod)
        {
            // Define field to hold info for this prop
            FieldBuilder stateField = context.TypeBuilder.DefineField("__propertyState_" + context.Property.Name, initMethod.ReturnType, FieldAttributes.Private);

            // Append to Init method code to call our initializer and store output in field
            context.InitMethodGenerator.Emit(OpCodes.Ldarg_0);
            context.InitMethodGenerator.Emit(OpCodes.Ldarg_0);
            context.InitMethodGenerator.Emit(OpCodes.Ldsfld, context.PropertyInfoField);
            context.InitMethodGenerator.EmitCall(OpCodes.Call, initMethod, null);
            context.InitMethodGenerator.Emit(OpCodes.Stfld, stateField);

            // Call getter method
            if (context.GetMethodGenerator != null)
            {
                context.GetMethodGenerator.Emit(OpCodes.Ldarg_0);
                context.GetMethodGenerator.Emit(OpCodes.Ldarg_0);
                context.GetMethodGenerator.Emit(OpCodes.Ldfld, stateField);

                getMethod = getMethod.Specialize(context.BaseClass, typeof(object), stateField.FieldType);

                context.GetMethodGenerator.EmitCall(OpCodes.Call, getMethod, null);
                if (context.Property.PropertyType.IsValueType && !getMethod.ReturnType.IsValueType)
                {
                    context.GetMethodGenerator.Emit(OpCodes.Unbox_Any, context.Property.PropertyType);
                }
                else if (!context.Property.PropertyType.IsValueType && getMethod.ReturnType.IsValueType)
                {
                    context.GetMethodGenerator.Emit(OpCodes.Box);
                }
            }

            // Call setter method
            if (context.SetMethodGenerator != null)
            {
                context.SetMethodGenerator.Emit(OpCodes.Ldarg_0);           // Instance for handler call
                context.SetMethodGenerator.Emit(OpCodes.Ldarg_0);           // Instance for field
                context.SetMethodGenerator.Emit(OpCodes.Ldfld, stateField); // Info field
                context.SetMethodGenerator.Emit(OpCodes.Ldarg_1);           // Value from set method

                setMethod = setMethod.Specialize(context.BaseClass, typeof(void), stateField.FieldType, context.Property.PropertyType);

                // If prop is value type but handler takes object, we must box
                if (context.Property.PropertyType.IsValueType && !setMethod.GetParameters().Last().ParameterType.IsValueType)
                {
                    context.SetMethodGenerator.Emit(OpCodes.Box, context.Property.PropertyType);
                }

                context.SetMethodGenerator.EmitCall(OpCodes.Call, setMethod, null);
            }
        }
Exemple #3
0
        /// <summary>
        /// Implements a property using a private backing field
        /// </summary>
        /// <param name="context"></param>
        private static void ImplementBackingField(PropertyBuilderContext context)
        {
            // Define field to hold info for this prop
            FieldBuilder valueField = context.TypeBuilder.DefineField("__backingField_" + context.Property.Name, context.Property.PropertyType, FieldAttributes.Private);

            if (context.GetMethodGenerator != null)
            {
                context.GetMethodGenerator.Emit(OpCodes.Ldarg_0);
                context.GetMethodGenerator.Emit(OpCodes.Ldfld, valueField);
            }

            if (context.SetMethodGenerator != null)
            {
                context.SetMethodGenerator.Emit(OpCodes.Ldarg_0);
                context.SetMethodGenerator.Emit(OpCodes.Ldarg_1);
                context.SetMethodGenerator.Emit(OpCodes.Stfld, valueField);
            }
        }
Exemple #4
0
        private static void ImplementSetInspector(PropertyBuilderContext context, Action <PropertyBuilderContext> implement, MethodInfo preSetInspector, MethodInfo postSetInspector)
        {
            // Call pre set inspector
            if (preSetInspector != null && context.SetMethodGenerator != null)
            {
                context.SetMethodGenerator.Emit(OpCodes.Ldarg_0);
                context.SetMethodGenerator.Emit(OpCodes.Ldsfld, context.PropertyInfoField);
                context.SetMethodGenerator.Emit(OpCodes.Ldarg_1);

                preSetInspector = preSetInspector.Specialize(context.BaseClass, typeof(void), typeof(PropertyInfo), context.Property.PropertyType);

                if (context.Property.PropertyType.IsValueType && !preSetInspector.GetParameters().Last().ParameterType.IsValueType)
                {
                    context.SetMethodGenerator.Emit(OpCodes.Box, context.Property.PropertyType);
                }

                context.SetMethodGenerator.EmitCall(OpCodes.Call, preSetInspector, null);
            }

            // Run real implementor now
            implement(context);

            // Call post set
            if (context.SetMethodGenerator != null && postSetInspector != null)
            {
                // Call inspector(layer, PropertyInfo, value)
                context.SetMethodGenerator.Emit(OpCodes.Ldarg_0);
                context.SetMethodGenerator.Emit(OpCodes.Ldsfld, context.PropertyInfoField);
                context.SetMethodGenerator.Emit(OpCodes.Ldarg_1);

                // Allow inspector be generic in property type
                postSetInspector = postSetInspector.Specialize(context.BaseClass, typeof(void), typeof(PropertyInfo), context.Property.PropertyType);

                if (context.Property.PropertyType.IsValueType && !postSetInspector.GetParameters().Last().ParameterType.IsValueType)
                {
                    context.SetMethodGenerator.Emit(OpCodes.Box, context.Property.PropertyType);
                }

                context.SetMethodGenerator.EmitCall(OpCodes.Call, postSetInspector, null);
            }
        }