private object CreateInstance(Type type, string[] args) { ConstructorInfo[] infoArray = type.GetConstructors(); List <ParameterInfo[]> matched = new List <ParameterInfo[]>(infoArray.Length); foreach (var con in infoArray) { ParameterInfo[] pArray = con.GetParameters(); if (pArray.Length == args.Length) { matched.Add(pArray); } } if (matched.Count <= 0) { throw new ApplicationException("Can't find the constructor with " + args.Length + " parameter(s) of type '" + type.AssemblyQualifiedName + "'"); } StringBuilder sb = new StringBuilder(); int j = 1; foreach (var paramArray in matched) { try { object[] realArgs = new object[paramArray.Length]; for (int i = 0; i < paramArray.Length; i++) { realArgs[i] = DataConvertor.GetValueByType(paramArray[i].ParameterType, args[i], null, null); } return(Activator.CreateInstance(type, realArgs)); } catch (Exception ex) { sb.AppendLine(j + ". " + ex.Message); } j++; } throw new ApplicationException("There are " + matched.Count + " matched constructor(s), but all failed to construct instance for type '" + type.AssemblyQualifiedName + "', detail error message: \r\n" + sb); }
private static object Convert(Type sourceType, Type targetType, object source, bool propertyNameIgnoreCase, string columnName, string propertyName, List <string> ignoreTargetProperties) { if (source != null && sourceType != source.GetType()) { sourceType = source.GetType(); } while (source != null && sourceType.IsGenericType && sourceType.GetGenericTypeDefinition() == typeof(Nullable <>) && sourceType.GetGenericArguments() != null && sourceType.GetGenericArguments().Length == 1) { if ((bool)Invoker.PropertyGet(sourceType, source, "HasValue", false, true)) { source = Invoker.PropertyGet(sourceType, source, "Value", false, true); } else { source = null; } sourceType = sourceType.GetGenericArguments()[0]; } // 通过循环找出源数据的真实类型(Nullable<>里的泛型参数类型) // 1. 为空 if (source == null || source == DBNull.Value) // 对象实例为空 { return(typeof(DataConvertor).GetMethod("GetDefaultValue", BindingFlags.Static | BindingFlags.Public).MakeGenericMethod(targetType).Invoke(null, null)); } // 2. 为简单类型或object TypeCode s_Code = Type.GetTypeCode(sourceType); TypeCode t_Code = Type.GetTypeCode(targetType); // enum的TypeCode为TypeCode.Int32 if (s_Code != TypeCode.Object || t_Code != TypeCode.Object || sourceType == typeof(object) || targetType == typeof(object)) { return(DataConvertor.GetValueByType(targetType, source, columnName, propertyName)); } // 3. 为实现了IDictionary<TKey, TValue>接口的集合 if (targetType.IsGenericType && targetType.GetGenericArguments().Length == 2 && typeof(IDictionary <int, int>).IsAssignableFrom(targetType.GetGenericTypeDefinition().MakeGenericType(typeof(int), typeof(int))) && sourceType.IsGenericType && sourceType.GetGenericArguments().Length == 2 && typeof(IDictionary <int, int>).IsAssignableFrom(sourceType.GetGenericTypeDefinition().MakeGenericType(typeof(int), typeof(int))) ) { object dictionary = Invoker.CreateInstance(targetType); Type target_key_type = targetType.GetGenericArguments()[0]; Type target_value_type = targetType.GetGenericArguments()[1]; Type source_key_type = sourceType.GetGenericArguments()[0]; Type source_value_type = sourceType.GetGenericArguments()[1]; IEnumerable iterator = (IEnumerable)source; foreach (object x in iterator) { Type xType = x.GetType(); object source_key = xType.GetProperty("Key").GetGetMethod().Invoke(x, new object[0]); object source_value = xType.GetProperty("Value").GetGetMethod().Invoke(x, new object[0]); object target_key = Convert(source_key_type, target_key_type, source_key, propertyNameIgnoreCase, columnName, propertyName, new List <string>(0)); object target_value = Convert(source_value_type, target_value_type, source_value, propertyNameIgnoreCase, columnName, propertyName, new List <string>(0)); Invoker.MethodInvoke(dictionary, "Add", target_key, target_value); } return(dictionary); } // 4. 为List<T>集合 if (targetType.IsGenericType && targetType.GetGenericArguments().Length == 1 && typeof(ICollection <int>).IsAssignableFrom(targetType.GetGenericTypeDefinition().MakeGenericType(typeof(int))) && sourceType.IsGenericType && sourceType.GetGenericArguments().Length == 1 && typeof(IEnumerable <int>).IsAssignableFrom(sourceType.GetGenericTypeDefinition().MakeGenericType(typeof(int))) ) { object list = Invoker.CreateInstance(targetType); Type listType = targetType.GetGenericArguments()[0]; Type s_eType = sourceType.GetGenericArguments()[0]; IEnumerable iterator = (IEnumerable)source; IList iList = list as IList; if (iList == null) { return(null); } foreach (object x in iterator) { object obj = Convert(s_eType, listType, x, propertyNameIgnoreCase, columnName, propertyName, new List <string>(0)); iList.Add(obj); } return(iList); } // 5. 为非集合的复杂类型 PropertyInfo[] sourceProArray = sourceType.GetProperties(BindingFlags.Public | BindingFlags.Instance); PropertyInfo[] targetProArray = targetType.GetProperties(BindingFlags.Public | BindingFlags.Instance); object target = Invoker.CreateInstance(targetType); foreach (var s_pro in sourceProArray) { if (!s_pro.CanRead) { continue; } foreach (var t_pro in targetProArray) { if (ignoreTargetProperties.Contains(t_pro.Name)) { continue; } StringComparison com = propertyNameIgnoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal; if (t_pro.CanWrite && string.Compare(t_pro.Name, s_pro.Name, com) == 0) { Type s_p_type = Invoker.GetPropertyType(sourceType, s_pro.Name); Type t_p_type = Invoker.GetPropertyType(targetType, t_pro.Name); object value = Invoker.PropertyGet(sourceType, source, s_pro.Name, false, true); Invoker.PropertySet(target, t_pro.Name, Convert(s_p_type, t_p_type, value, propertyNameIgnoreCase, columnName + (columnName.Length > 0 ? "." : "") + s_pro.Name, propertyName + (propertyName.Length > 0 ? "." : "") + t_pro.Name, new List <string>())); break; } } } return(target); }