Beispiel #1
0
        private void ImplementProtectedFieldAccessors()
        {
            // For protected fields to be accessible from the derived type in Silverlight,
            // we need to create public helper methods that expose them. These methods are
            // used by the IOldDynamicObject implementation (in UserTypeOps.GetRuleHelper)

            FieldInfo[] fields = _baseType.GetFields(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.FlattenHierarchy);
            foreach (FieldInfo fi in fields)
            {
                if (!fi.IsFamily && !fi.IsFamilyOrAssembly)
                {
                    continue;
                }

                List <string> fieldAccessorNames = new List <string>();

                PropertyBuilder  pb          = _tb.DefineProperty(fi.Name, PropertyAttributes.None, fi.FieldType, Type.EmptyTypes);
                MethodAttributes methodAttrs = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName;
                if (fi.IsStatic)
                {
                    methodAttrs |= MethodAttributes.Static;
                }

                MethodBuilder method;
                method = _tb.DefineMethod(FieldGetterPrefix + fi.Name, methodAttrs,
                                          fi.FieldType, Type.EmptyTypes);
                ILGen il = CreateILGen(method.GetILGenerator());
                if (!fi.IsStatic)
                {
                    il.EmitLoadArg(0);
                }

                if (fi.IsLiteral)
                {
                    // literal fields need to be inlined directly in here... We use GetRawConstant
                    // which will work even in partial trust if the constant is protected.
                    object value = fi.GetRawConstantValue();
                    switch (Type.GetTypeCode(fi.FieldType))
                    {
                    case TypeCode.Boolean:
                        if ((bool)value)
                        {
                            il.Emit(OpCodes.Ldc_I4_1);
                        }
                        else
                        {
                            il.Emit(OpCodes.Ldc_I4_0);
                        }
                        break;

                    case TypeCode.Byte: il.Emit(OpCodes.Ldc_I4, (byte)value); break;

                    case TypeCode.Char: il.Emit(OpCodes.Ldc_I4, (char)value); break;

                    case TypeCode.Double: il.Emit(OpCodes.Ldc_R8, (double)value); break;

                    case TypeCode.Int16: il.Emit(OpCodes.Ldc_I4, (short)value); break;

                    case TypeCode.Int32: il.Emit(OpCodes.Ldc_I4, (int)value); break;

                    case TypeCode.Int64: il.Emit(OpCodes.Ldc_I8, (long)value); break;

                    case TypeCode.SByte: il.Emit(OpCodes.Ldc_I4, (sbyte)value); break;

                    case TypeCode.Single: il.Emit(OpCodes.Ldc_R4, (float)value); break;

                    case TypeCode.String: il.Emit(OpCodes.Ldstr, (string)value); break;

                    case TypeCode.UInt16: il.Emit(OpCodes.Ldc_I4, (ushort)value); break;

                    case TypeCode.UInt32: il.Emit(OpCodes.Ldc_I4, (uint)value); break;

                    case TypeCode.UInt64: il.Emit(OpCodes.Ldc_I8, (ulong)value); break;
                    }
                }
                else
                {
                    il.EmitFieldGet(fi);
                }
                il.Emit(OpCodes.Ret);

                pb.SetGetMethod(method);
                fieldAccessorNames.Add(method.Name);

                if (!fi.IsLiteral && !fi.IsInitOnly)
                {
                    method = _tb.DefineMethod(FieldSetterPrefix + fi.Name, methodAttrs,
                                              null, new Type[] { fi.FieldType });
                    method.DefineParameter(1, ParameterAttributes.None, "value");
                    il = CreateILGen(method.GetILGenerator());
                    il.EmitLoadArg(0);
                    if (!fi.IsStatic)
                    {
                        il.EmitLoadArg(1);
                    }
                    il.EmitFieldSet(fi);
                    il.Emit(OpCodes.Ret);
                    pb.SetSetMethod(method);

                    fieldAccessorNames.Add(method.Name);
                }

                _specialNames.SetSpecialName(fi.Name, fieldAccessorNames);
            }
        }