protected virtual Action <object, TType> GetMemberSetterInternal <TType>(MemberInfo member)
        {
            var key = new MemberInfoDelegateCacheKey(member, typeof(TType));

            lock (MemberSetterCache)
            {
                Delegate action;
                if (!MemberSetterCache.TryGetValue(key, out action))
                {
                    var declaringType = member.DeclaringType;
                    var fieldInfo     = member as FieldInfo;
#if NET_STANDARD
                    if (declaringType.GetTypeInfo().IsValueType)
#else
                    if (declaringType.IsValueType)
#endif
                    {
                        Action <object, TType> result;
                        if (fieldInfo == null)
                        {
                            var propertyInfo = (PropertyInfo)member;
                            result = propertyInfo.SetValue <TType>;
                        }
                        else
                        {
                            result = fieldInfo.SetValue <TType>;
                        }
                        MemberSetterCache[key] = result;
                        return(result);
                    }

                    Expression expression;
                    var        targetParameter = Expression.Parameter(typeof(object), "instance");
                    var        valueParameter  = Expression.Parameter(typeof(TType), "value");
                    var        target          = ConvertIfNeed(targetParameter, declaringType, false);
                    if (fieldInfo == null)
                    {
                        var        propertyInfo = member as PropertyInfo;
                        MethodInfo setMethod    = null;
                        if (propertyInfo != null)
                        {
                            setMethod = propertyInfo.GetSetMethod(true);
                        }
                        Should.MethodBeSupported(propertyInfo != null && setMethod != null,
                                                 "supports only properties (non-readonly) and fields");
                        var valueExpression = ConvertIfNeed(valueParameter, propertyInfo.PropertyType, false);
                        expression = Expression.Call(setMethod.IsStatic ? null : ConvertIfNeed(target, declaringType, false), setMethod, valueExpression);
                        GenerateSetterCode(member, typeof(TType), propertyInfo.PropertyType);
                    }
                    else
                    {
                        expression = Expression.Field(fieldInfo.IsStatic ? null : ConvertIfNeed(target, declaringType, false), fieldInfo);
                        expression = Expression.Assign(expression, ConvertIfNeed(valueParameter, fieldInfo.FieldType, false));
                        GenerateSetterCode(member, typeof(TType), fieldInfo.FieldType);
                    }
                    action = Expression
                             .Lambda <Action <object, TType> >(expression, targetParameter, valueParameter)
                             .Compile();
                    MemberSetterCache[key] = action;
                }
                return((Action <object, TType>)action);
            }
        }
Пример #2
0
 public object ConvertBack(object value, Type targetType, object parameter, string language)
 {
     Should.MethodBeSupported(false, "ConvertBack()");
     return(null);
 }
Пример #3
0
        /// <summary>
        ///     Gets a delegate to set specified value in the specified <see cref="MemberInfo" /> in a value type target, can be
        ///     used with reference type.
        /// </summary>
        /// <typeparam name="TType">Type of the value.</typeparam>
        /// <param name="member">
        ///     The specified <see cref="MemberInfo" />.
        /// </param>
        /// <returns>
        ///     An instance of <see cref="Action{TOwner,TType}" />
        /// </returns>
        public virtual Action <object, TType> GetMemberSetter <TType>(MemberInfo member)
        {
            Should.NotBeNull(member, "member");
            lock (MemberSetterCache)
            {
                Delegate action;
                if (!MemberAccessCache.TryGetValue(member, out action) || !(action is Action <object, TType>))
                {
                    var declaringType = GetDeclaringType(member);
                    var fieldInfo     = member as FieldInfo;
#if PCL_WINRT
                    if (declaringType.GetTypeInfo().IsValueType)
#else
                    if (declaringType.IsValueType)
#endif
                    {
                        Action <object, TType> result;
                        if (fieldInfo == null)
                        {
                            var propertyInfo = (PropertyInfo)member;
                            result = propertyInfo.SetValue <TType>;
                        }
                        else
                        {
                            result = fieldInfo.SetValue <TType>;
                        }
                        MemberAccessCache[member] = result;
                        return(result);
                    }

                    Expression expression;
                    var        targetParameter = Expression.Parameter(typeof(object), "instance");
                    var        valueParameter  = Expression.Parameter(typeof(TType), "value");
                    var        target          = ConvertIfNeed(targetParameter, declaringType, false);
                    if (fieldInfo == null)
                    {
                        var        propertyInfo = member as PropertyInfo;
                        MethodInfo setMethod    = null;
                        if (propertyInfo != null)
                        {
                            setMethod = propertyInfo.GetSetMethod(true);
                        }
                        Should.MethodBeSupported(propertyInfo != null && setMethod != null,
                                                 "supports only properties(non-readonly) and fields");
                        var valueExpression = ConvertIfNeed(valueParameter, propertyInfo.PropertyType, false);
                        expression =
                            Expression.Call(setMethod.IsStatic ? null : ConvertIfNeed(target, declaringType, false),
                                            setMethod, valueExpression);
                    }
                    else
                    {
                        expression = Expression.Field(fieldInfo.IsStatic ? null : ConvertIfNeed(target, declaringType, false), fieldInfo);
                        expression = Assign(expression, ConvertIfNeed(valueParameter, fieldInfo.FieldType, false));
                    }
                    action = Expression
                             .Lambda <Action <object, TType> >(expression, targetParameter, valueParameter)
                             .Compile();
                    MemberAccessCache[member] = action;
                }
                return((Action <object, TType>)action);
            }
        }
Пример #4
0
 public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
 {
     Should.MethodBeSupported(false, "ConvertBack()");
     return(null);
 }
Пример #5
0
 /// <summary>
 ///     Navigates forward.
 /// </summary>
 public virtual void GoForward()
 {
     Should.MethodBeSupported(false, "GoForward()");
 }
Пример #6
0
 public object ConvertBack(object value, Type targetType, object parameter, string language)
 {
     Should.MethodBeSupported(_convertBack != null, "ConvertBack");
     return(_convertBack(value, targetType, parameter, language));
 }
Пример #7
0
 /// <summary>
 ///     Converts a value.
 /// </summary>
 /// <returns>
 ///     A converted value. If the method returns null, the valid null value is used.
 /// </returns>
 /// <param name="value">The value that is produced by the binding target.</param>
 /// <param name="targetType">The type to convert to.</param>
 /// <param name="parameter">The converter parameter to use.</param>
 /// <param name="culture">The culture to use in the converter.</param>
 /// <param name="context">The current context to use in the converter.</param>
 public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture, IDataContext context)
 {
     Should.MethodBeSupported(_convertBack != null, "ConvertBack");
     return(_convertBack(value, targetType, parameter, culture.Name));
 }