コード例 #1
0
        public static GenericSetter CreateGenericSetter(Type type, MemberInfo memberInfo)
        {
            if (memberInfo == null)
            {
                throw new ArgumentNullException("propertyInfo");
            }

            // if has no write
            if (memberInfo is PropertyInfo && (memberInfo as PropertyInfo).CanWrite == false)
            {
                return(null);
            }

#if NET35
            // do not use Expression in Structs (there is no Expression.Unbox in NET3.5)
            if (type.IsValueType)
            {
                // if member is property, use GetSetMethod
                if (memberInfo is PropertyInfo)
                {
                    var setMethod = (memberInfo as PropertyInfo).GetSetMethod();

                    return((t, v) => setMethod.Invoke(t, new[] { v }));
                }
                else
                {
                    return(null); // no field on Structs
                }
            }
#endif
            var dataType = memberInfo is PropertyInfo ?
                           (memberInfo as PropertyInfo).PropertyType :
                           (memberInfo as FieldInfo).FieldType;

            var target = Expression.Parameter(typeof(object), "obj");
            var value  = Expression.Parameter(typeof(object), "val");

#if NET35
            var castTarget = Expression.Convert(target, type);
#else
            var castTarget = type.GetTypeInfo().IsValueType ?
                             Expression.Unbox(target, type) :
                             Expression.Convert(target, type);
#endif

            var castValue = Expression.ConvertChecked(value, dataType);

            var accessor =
                memberInfo is PropertyInfo?Expression.Property(castTarget, memberInfo as PropertyInfo) :
                    memberInfo is FieldInfo?Expression.Field(castTarget, memberInfo as FieldInfo) : null;

#if NET35
            var assign = ExpressionExtensions.Assign(accessor, castValue);
#else
            var assign = Expression.Assign(accessor, castValue);
#endif
            var conv = Expression.Convert(assign, typeof(object));

            return(Expression.Lambda <GenericSetter>(conv, target, value).Compile());
        }
コード例 #2
0
        public static GenericSetter CreateGenericSetter(Type type, MemberInfo memberInfo)
        {
            if (memberInfo == null)
            {
                throw new ArgumentNullException("propertyInfo");
            }

            var fieldInfo    = memberInfo as FieldInfo;
            var propertyInfo = memberInfo as PropertyInfo;

            // if is property and has no write
            if (memberInfo is PropertyInfo && propertyInfo.CanWrite == false)
            {
                return(null);
            }

            // if *Structs*, use direct reflection - net35 has no Expression.Unbox to cast target
            if (type.GetTypeInfo().IsValueType)
            {
                return(memberInfo is FieldInfo ?
                       (GenericSetter)fieldInfo.SetValue :
                       ((t, v) => propertyInfo.SetValue(t, v, null)));
            }

            var dataType = memberInfo is PropertyInfo ?
                           propertyInfo.PropertyType :
                           fieldInfo.FieldType;

            var target = Expression.Parameter(typeof(object), "obj");
            var value  = Expression.Parameter(typeof(object), "val");

            var castTarget = Expression.Convert(target, type);
            var castValue  = Expression.ConvertChecked(value, dataType);

            var accessor = memberInfo is PropertyInfo?
                           Expression.Property(castTarget, propertyInfo) :
                               Expression.Field(castTarget, fieldInfo);

            var assign = ExpressionExtensions.Assign(accessor, castValue);
            var conv   = Expression.Convert(assign, typeof(object));

            return(Expression.Lambda <GenericSetter>(conv, target, value).Compile());
        }
コード例 #3
0
        public static GenericSetter CreateGenericSetter(Type type, MemberInfo memberInfo)
        {
            if (memberInfo == null)
            {
                throw new ArgumentNullException("propertyInfo");
            }

            var fieldInfo    = memberInfo as FieldInfo;
            var propertyInfo = memberInfo as PropertyInfo;

            // // if is property and has no write
            // hh: private setters
            if (memberInfo is PropertyInfo && propertyInfo.CanWrite == false)
            {
                PropertyInfo pi = null;
                var          bt = type;
                do
                {
                    bt = bt.GetTypeInfo().BaseType;
                    if (bt == null)
                    {
                        break;
                    }

                    pi = bt.GetProperties(BindingFlags.Instance | BindingFlags.FlattenHierarchy | BindingFlags.NonPublic | BindingFlags.Public).FirstOrDefault(x => x.Name == propertyInfo.Name);
                } while (bt != null && (pi == null || !pi.CanWrite));

                if (pi == null)
                {
                    return(null);
                }
                return((t, v) => pi.SetValue(t, v, null));
            }

            // if *Structs*, use direct reflection - net35 has no Expression.Unbox to cast target
            if (type.GetTypeInfo().IsValueType)
            {
                return(memberInfo is FieldInfo ?
                       (GenericSetter)fieldInfo.SetValue :
                       ((t, v) => propertyInfo.SetValue(t, v, null)));
            }

            var dataType = memberInfo is PropertyInfo ?
                           propertyInfo.PropertyType :
                           fieldInfo.FieldType;

            var target = Expression.Parameter(typeof(object), "obj");
            var value  = Expression.Parameter(typeof(object), "val");

            var castTarget = Expression.Convert(target, type);
            var castValue  = Expression.ConvertChecked(value, dataType);

            var accessor = memberInfo is PropertyInfo?
                           Expression.Property(castTarget, propertyInfo) :
                               Expression.Field(castTarget, fieldInfo);

            var assign = ExpressionExtensions.Assign(accessor, castValue);
            var conv   = Expression.Convert(assign, typeof(object));

            return(Expression.Lambda <GenericSetter>(conv, target, value).Compile());
        }