예제 #1
0
        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);
        }
예제 #2
0
        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);
        }