/// <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); }