Пример #1
0
        public FieldInfo(TypeInfo typeInfo, System.Reflection.FieldInfo info, Type overrideType = null)
            : base(typeInfo, info, null, typeInfo.TypeCache.GetTypeInfo(overrideType ?? info.FieldType))
        {
            this.callGet = new Lazy <Func <object, object> >(() =>
            {
                ParameterExpression targetParam = Expression.Parameter(typeof(object), null);
                Expression castTarget           = ReflectionUtility.Convert(targetParam, typeInfo);
                Expression getField             = Expression.Field(castTarget, info);
                Expression castField            = Expression.Convert(getField, typeof(object));

                return(ReflectionUtility.CompileLambda <Func <object, object> >(castField, targetParam));
            });

            this.callSet = new Lazy <Action <object, object> >(() =>
            {
                ParameterExpression targetParam = Expression.Parameter(typeof(object), null);
                ParameterExpression valueParam  = Expression.Parameter(typeof(object), null);
                Expression castTarget           = ReflectionUtility.Convert(targetParam, typeInfo);
                Expression castValue            = Expression.Convert(valueParam, info.FieldType);
                Expression accessField          = Expression.Field(castTarget, info);
                Expression setField             = Expression.Assign(accessField, castValue);

                return(ReflectionUtility.CompileLambda <Action <object, object> >(setField, targetParam, valueParam));
            });
        }
Пример #2
0
        public PropertyInfo(TypeInfo typeInfo, System.Reflection.PropertyInfo info)
            : base(typeInfo, info, null, typeInfo.TypeCache.GetTypeInfo(info.PropertyType))
        {
            this.callGet = new Lazy <Func <object, object> >(() =>
            {
                ParameterExpression targetParam = Expression.Parameter(typeof(object), null);
                Expression castTarget           = ReflectionUtility.Convert(targetParam, typeInfo);
                MemberExpression propertyAccess = Expression.MakeMemberAccess(castTarget, info);
                Expression castProperty         = Expression.Convert(propertyAccess, typeof(object));

                return(ReflectionUtility.CompileLambda <Func <object, object> >(castProperty, targetParam));
            });

            this.callSet = new Lazy <Action <object, object> >(() =>
            {
                System.Reflection.MethodInfo setMethod = info.GetSetMethod(nonPublic: true);
                if (setMethod == null)
                {
                    throw JsonException.New(Resources.Convert_NoSetter, info.Name, info.DeclaringType.FullName);
                }

                ParameterExpression targetParam = Expression.Parameter(typeof(object), null);
                ParameterExpression valueParam  = Expression.Parameter(typeof(object), null);
                Expression castTarget           = ReflectionUtility.Convert(targetParam, typeInfo);
                Expression castValue            = Expression.Convert(valueParam, info.PropertyType);
                Expression propertySet          = Expression.Call(castTarget, setMethod, castValue);

                return(ReflectionUtility.CompileLambda <Action <object, object> >(propertySet, targetParam, valueParam));
            });
        }
Пример #3
0
        private DictionaryInfo(TypeInfo typeInfo, System.Reflection.PropertyInfo info, TypeInfo keyType, TypeInfo valueType)
            : base(typeInfo, info, keyType, valueType)
        {
            this.info = info;

            this.callTryGetValue = new Lazy <TryGetValueDelegate>(() =>
            {
                System.Reflection.MethodInfo tryGetMethod = typeInfo.Type.GetMethod("TryGetValue");
                if (tryGetMethod == null)
                {
                    return(null);
                }

                ParameterExpression targetParam   = Expression.Parameter(typeof(object), null);
                ParameterExpression keyParam      = Expression.Parameter(typeof(object), null);
                ParameterExpression outValueParam = Expression.Parameter(typeof(object).MakeByRefType(), null);
                Expression castTarget             = ReflectionUtility.Convert(targetParam, typeInfo);
                Expression castKey    = ReflectionUtility.Convert(keyParam, keyType);
                Expression callTryGet = Expression.Call(castTarget, tryGetMethod, castKey, outValueParam);

                return(ReflectionUtility.CompileLambda <TryGetValueDelegate>(callTryGet, targetParam, keyParam, outValueParam));
            });

            this.callGet = new Lazy <Func <object, object, object> >(() =>
            {
                System.Reflection.MethodInfo getMethod = info.GetGetMethod(nonPublic: false);
                if (getMethod == null)
                {
                    return(null);
                }

                ParameterExpression targetParam = Expression.Parameter(typeof(object), null);
                ParameterExpression keyParam    = Expression.Parameter(typeof(object), null);
                Expression castTarget           = ReflectionUtility.Convert(targetParam, typeInfo);
                Expression castKey = ReflectionUtility.Convert(keyParam, keyType);
                Expression callGet = Expression.Call(castTarget, getMethod, castKey);

                return(ReflectionUtility.CompileLambda <Func <object, object, object> >(callGet, targetParam, keyParam));
            });

            this.callSet = new Lazy <Action <object, object, object> >(() =>
            {
                System.Reflection.MethodInfo setMethod = info.GetSetMethod(nonPublic: false);
                if (setMethod == null)
                {
                    return(null);
                }

                ParameterExpression targetParam = Expression.Parameter(typeof(object), null);
                ParameterExpression keyParam    = Expression.Parameter(typeof(object), null);
                ParameterExpression valueParam  = Expression.Parameter(typeof(object), null);
                Expression castTarget           = ReflectionUtility.Convert(targetParam, typeInfo);
                Expression castKey   = ReflectionUtility.Convert(keyParam, keyType);
                Expression castValue = ReflectionUtility.Convert(valueParam, valueType);
                Expression callSet   = Expression.Call(castTarget, setMethod, castKey, castValue);

                return(ReflectionUtility.CompileLambda <Action <object, object, object> >(callSet, targetParam, keyParam, valueParam));
            });
        }
Пример #4
0
 private Lazy <Action <object, StreamingContext> > CreateStreamingContextCall(TypeInfo typeInfo, System.Reflection.MethodInfo methodInfo)
 {
     return(new Lazy <Action <object, StreamingContext> >(() =>
     {
         ParameterExpression targetParam = Expression.Parameter(typeof(object), null);
         ParameterExpression contextParam = Expression.Parameter(typeof(StreamingContext), null);
         Expression castTarget = Expression.Convert(targetParam, typeInfo.Type);
         Expression callMethod = Expression.Call(castTarget, methodInfo, contextParam);
         return ReflectionUtility.CompileLambda <Action <object, StreamingContext> >(callMethod, targetParam, contextParam);
     }));
 }
Пример #5
0
 private void InitValueTypeDefault(TypeInfo typeInfo)
 {
     this.IsValueTypeDefault = new Lazy <Func <object, bool> >(() =>
     {
         ParameterExpression valueParam = Expression.Parameter(typeof(object), null);
         Expression defaultValue        = Expression.Default(typeInfo.Type);
         Expression defaultObject       = Expression.Convert(defaultValue, typeof(object));
         Expression compare             = Expression.Equal(valueParam, defaultObject);
         return(ReflectionUtility.CompileLambda <Func <object, bool> >(compare, valueParam));
     });
 }
Пример #6
0
        private CollectionInfo(TypeInfo typeInfo, System.Reflection.PropertyInfo info, System.Reflection.MethodInfo addMethod, TypeInfo valueType)
            : base(typeInfo, info, null, valueType)
        {
            this.callAdd = new Lazy <Action <object, object> >(() =>
            {
                ParameterExpression targetParam = Expression.Parameter(typeof(object), null);
                ParameterExpression valueParam  = Expression.Parameter(typeof(object), null);
                Expression castTarget           = ReflectionUtility.Convert(targetParam, typeInfo);
                Expression castValue            = ReflectionUtility.Convert(valueParam, valueType);
                Expression callAdd = Expression.Call(castTarget, addMethod, castValue);

                return(ReflectionUtility.CompileLambda <Action <object, object> >(callAdd, targetParam, valueParam));
            });
        }
Пример #7
0
        private KvpCollectionInfo(
            TypeInfo typeInfo,
            System.Reflection.PropertyInfo info,
            System.Reflection.MethodInfo addMethod,
            bool mustBeKvp,
            TypeInfo kvpType,
            TypeInfo keyType,
            TypeInfo valueType)
            : base(typeInfo, info, keyType, valueType)
        {
            this.mustBeKvp = mustBeKvp;

            this.constructKvp = new Lazy <Func <object, object, object> >(() =>
            {
                System.Reflection.ConstructorInfo kvpConstructor = kvpType.Type.GetConstructor(new Type[] { keyType.Type, valueType.Type });

                ParameterExpression keyParam   = Expression.Parameter(typeof(object), null);
                ParameterExpression valueParam = Expression.Parameter(typeof(object), null);
                Expression castKey             = ReflectionUtility.Convert(keyParam, keyType);
                Expression castValue           = ReflectionUtility.Convert(valueParam, valueType);
                Expression newKvp     = Expression.New(kvpConstructor, castKey, castValue);
                Expression convertKvp = Expression.Convert(newKvp, typeof(object));

                return(ReflectionUtility.CompileLambda <Func <object, object, object> >(convertKvp, keyParam, valueParam));
            });

            this.callAdd = new Lazy <Action <object, object> >(() =>
            {
                ParameterExpression targetParam = Expression.Parameter(typeof(object), null);
                ParameterExpression valueParam  = Expression.Parameter(typeof(object), null);
                Expression castTarget           = ReflectionUtility.Convert(targetParam, typeInfo);
                Expression castValue            = ReflectionUtility.Convert(valueParam, mustBeKvp ? kvpType : valueType);
                Expression callAdd = Expression.Call(castTarget, addMethod, castValue);

                return(ReflectionUtility.CompileLambda <Action <object, object> >(callAdd, targetParam, valueParam));
            });
        }
Пример #8
0
        private void InitConstructors(TypeInfo typeInfo)
        {
            Type type = typeInfo.Type;

            if (type.GetConstructor(Type.EmptyTypes) is System.Reflection.ConstructorInfo defaultConstructor)
            {
                this.DefaultConstructor = new Lazy <Func <object> >(() =>
                {
                    Expression createObj  = typeInfo.IsValueType ? Expression.New(type) : Expression.New(defaultConstructor);
                    Expression convertObj = typeInfo.IsValueType ? Expression.Convert(createObj, typeof(object)) : createObj;
                    return(ReflectionUtility.CompileLambda <Func <object> >(convertObj));
                });
            }

            if (typeInfo.IsArray || typeInfo.GenericTypeDefinition == typeof(List <>) || typeInfo.GenericTypeDefinition == typeof(Dictionary <,>))
            {
                if (type.GetConstructor(new Type[] { typeof(int) }) is System.Reflection.ConstructorInfo capacityConstructor)
                {
                    this.CapacityConstructor = new Lazy <Func <int, object> >(() =>
                    {
                        ParameterExpression capacityParam = Expression.Parameter(typeof(int), null);
                        Expression createObj  = Expression.New(capacityConstructor, capacityParam);
                        Expression convertObj = typeInfo.IsValueType ? Expression.Convert(createObj, typeof(object)) : createObj;
                        return(ReflectionUtility.CompileLambda <Func <int, object> >(convertObj, capacityParam));
                    });
                }
            }

            if (typeInfo.GenericTypeDefinition == typeof(List <>) && type.GetMethod("ToArray") is System.Reflection.MethodInfo toArrayMethod)
            {
                this.ToArrayMethod = new Lazy <Func <object, Array> >(() =>
                {
                    ParameterExpression targetParam = Expression.Parameter(typeof(object), null);
                    Expression targetCast           = Expression.Convert(targetParam, toArrayMethod.DeclaringType);
                    Expression callToArray          = Expression.Call(targetCast, toArrayMethod);
                    Expression resultCast           = Expression.Convert(callToArray, typeof(Array));
                    return(ReflectionUtility.CompileLambda <Func <object, Array> >(resultCast, targetParam));
                });
            }

            if (typeInfo.GenericTypeDefinition == typeof(KeyValuePair <,>) &&
                type.GetMethod("get_Key") is System.Reflection.MethodInfo getKeyMethod &&
                type.GetMethod("get_Value") is System.Reflection.MethodInfo getValueMethod)
            {
                Type   kvpType = typeof(KeyValuePair <object, object>);
                Type[] args    = type.GetGenericArguments();

                this.ToKeyValuePairMethod = new Lazy <Func <object, KeyValuePair <object, object> > >(() =>
                {
                    ParameterExpression targetParam = Expression.Parameter(typeof(object), null);
                    Expression targetCast           = Expression.Convert(targetParam, type);
                    Expression keyCast   = Expression.Convert(Expression.Call(targetCast, getKeyMethod), typeof(object));
                    Expression valueCast = Expression.Convert(Expression.Call(targetCast, getValueMethod), typeof(object));
                    Expression newKvp    = Expression.New(kvpType.GetConstructor(new Type[] { typeof(object), typeof(object) }), keyCast, valueCast);

                    Expression result = Expression.Condition(
                        Expression.ReferenceEqual(targetParam, Expression.Constant(null)),
                        Expression.Default(kvpType),
                        newKvp, kvpType);

                    return(ReflectionUtility.CompileLambda <Func <object, KeyValuePair <object, object> > >(result, targetParam));
                });
            }
        }