예제 #1
0
 internal Accessor(PropertyInfo pi, DGet <T, V> dget, DSet <T, V> dset, DRSet <T, V> drset, MetaAccessor <T, V2> storage)
 {
     this.pi      = pi;
     this.dget    = dget;
     this.dset    = dset;
     this.drset   = drset;
     this.storage = storage;
 }
예제 #2
0
        internal static MetaAccessor Create(Type objectType, PropertyInfo pi, MetaAccessor storageAccessor)
        {
            Delegate   dset      = null;
            Delegate   drset     = null;
            Type       dgetType  = typeof(DGet <,>).MakeGenericType(objectType, pi.PropertyType);
            MethodInfo getMethod = pi.GetGetMethod(true);

            Delegate dget = Delegate.CreateDelegate(dgetType, getMethod, true);

            if (dget == null)
            {
                throw Error.CouldNotCreateAccessorToProperty(objectType, pi.PropertyType, pi);
            }

            if (pi.CanWrite)
            {
                if (!objectType.IsValueType)
                {
                    dset = Delegate.CreateDelegate(typeof(DSet <,>).MakeGenericType(objectType, pi.PropertyType), pi.GetSetMethod(true), true);
                }
                else
                {
                    DynamicMethod mset = new DynamicMethod(
                        "xset_" + pi.Name,
                        typeof(void),
                        new Type[] { objectType.MakeByRefType(), pi.PropertyType },
                        true
                        );

                    ILGenerator gen = mset.GetILGenerator();
                    gen.Emit(OpCodes.Ldarg_0);

                    if (!objectType.IsValueType)
                    {
                        gen.Emit(OpCodes.Ldind_Ref);
                    }

                    gen.Emit(OpCodes.Ldarg_1);
                    gen.Emit(OpCodes.Call, pi.GetSetMethod(true));
                    gen.Emit(OpCodes.Ret);
                    drset = mset.CreateDelegate(typeof(DRSet <,>).MakeGenericType(objectType, pi.PropertyType));
                }
            }

            Type saType = (storageAccessor != null) ? storageAccessor.Type : pi.PropertyType;

            return((MetaAccessor)Activator.CreateInstance(
                       typeof(Accessor <, ,>).MakeGenericType(objectType, pi.PropertyType, saType),
                       BindingFlags.Instance | BindingFlags.NonPublic, null,
                       new object[] { pi, dget, dset, drset, storageAccessor }, null
                       ));
        }