Example #1
0
        /// <summary>
        /// 根据名称设置指定属性或字段的值。
        /// </summary>
        /// <param name="instance">要设置属性或字段值的实例。</param>
        /// <param name="name">属性或字段的名称。</param>
        /// <param name="ignoreCase">指定是否忽略属性或字段名称的大小写。</param>
        /// <param name="value">要设置的值。</param>
        public void SetValue(object instance, string name, object value, bool ignoreCase = false)
        {
            if (value == null)
            {
                return;
            }

            var comparer = ignoreCase ? StringComparison.CurrentCultureIgnoreCase : StringComparison.CurrentCulture;
            var m        = datas.FirstOrDefault(mi => mi.Name.Equals(name, comparer));

            if (m == null)
            {
                throw new MemberNotExistsException(name);
            }
            var setter  = setters[m, TypeHelper.GetPropertyOrFieldSetter];
            var desType = GetMemberType(m.Name);

            var srcType = value.GetType();

            if (!desType.IsAssignableFrom(srcType))
            {
                if (desType == typeof(string))
                {
                    var toString = srcType.GetMethod("ToString", Type.EmptyTypes);
                    value = toString.Invoke(value, null);
                }
                else if (desType.IsEnumerable() && srcType.IsEnumerable())
                {
                    var etype = TypeExtension.GetElementType(desType);
                    var cast  = typeof(Enumerable).GetMethod("Cast", BindingFlags.Static | BindingFlags.Public).MakeGenericMethod(etype);
                    value = cast.Invoke(null, new[] { value });
                    if (desType.IsArray)
                    {
                        var toArray = typeof(Enumerable).GetMethod("ToArray", BindingFlags.Static | BindingFlags.Public).MakeGenericMethod(etype);
                        value = toArray.Invoke(null, new[] { value });
                    }
                    if (desType.IsGenericType && (desType.GetGenericTypeDefinition() == typeof(IList <>) || desType.GetGenericTypeDefinition() == typeof(List <>)))
                    {
                        var toList = typeof(Enumerable).GetMethod("ToList", BindingFlags.Static | BindingFlags.Public).MakeGenericMethod(etype);
                        value = toList.Invoke(null, new[] { value });
                    }
                }
                else if (srcType == typeof(string))
                {
                    var strValue = value.ToString();
                    if (desType == typeof(Guid))
                    {
                        value = string.IsNullOrWhiteSpace(strValue) ? Guid.Empty : Guid.Parse(strValue);
                    }
                    else
                    {
                        var parse = desType.GetMethod("Parse", BindingFlags.Static | BindingFlags.Public, null, new[] { srcType }, null);
                        if (parse != null)
                        {
                            value = parse.Invoke(null, new[] { value });
                        }
                        else
                        {
                            throw new InvalidCastException(string.Format("无法将 \"{0}\" 类型的值转换为 \"{1}\" 类型。", srcType, desType));
                        }
                    }
                }
            }
            setter(instance, value);
        }