一、将Array转换为DataTable:
/// <summary> /// 转换对象数组为数据表 /// </summary> /// <param name="objs">对象数组</param> /// <param name="members">需要转换的成员</param> /// <param name="ignoreMembers">忽略转换的成员</param> /// <returns>返回数据表</returns> public virtual DataTable ConvertTable(object[] objs, string[] members, string[] ignoreMembers) { // 创建目标数据表 DataTable dataTable = new DataTable(); // 获取对象数组元素类型 Type type = objs.GetType().GetElementType(); // 创建要转换的对象成员字典 Dictionary<string, MemberInfo> memberInfos = new Dictionary<string, MemberInfo>(); // 获取成员字段 FieldInfo[] fieldInfos = type.GetFields(); // 遍历成员字段,添加要转换的成员字段到字典中 foreach (FieldInfo fieldInfo in fieldInfos) { // 获取当前字段名 string name = fieldInfo.Name; // 判断当前字段是否需要转换 if ((members == null || members.Length <= 0 || members.Contains("*") || members.Contains(name)) && (ignoreMembers == null || ignoreMembers.Length <= 0 || (!ignoreMembers.Contains("*") && !ignoreMembers.Contains(name)))) { // 判断当前字段是否是公开的 if (fieldInfo.IsPublic) { // 添加要转换的成员字段 memberInfos[name] = fieldInfo; } } } // 获取成员属性 PropertyInfo[] propertyInfos = type.GetProperties(); // 遍历成员属性,添加要转换的成员属性到字典中 foreach (PropertyInfo propertyInfo in propertyInfos) { // 获取当前属性名 string name = propertyInfo.Name; // 判断当前属性是否需要转换 if ((members == null || members.Length <= 0 || members.Contains("*") || members.Contains(name)) && (ignoreMembers == null || ignoreMembers.Length <= 0 || (!ignoreMembers.Contains("*") && !ignoreMembers.Contains(name)))) { // 判断当前属性是否可读 if (propertyInfo.CanRead) { // 获取当前属性的GET访问器 MethodInfo methodInfo = propertyInfo.GetGetMethod(); // 判断当前属性的GET访问器是否是公开的 if (methodInfo.IsPublic) { // 添加要转换的成员属性 memberInfos[name] = propertyInfo; } } } } // 遍历要转换的对象成员字典,添加数据列 foreach (KeyValuePair<string, MemberInfo> item in memberInfos) { // 添加数据列 DataColumn dataColumn = dataTable.Columns.Add(item.Key); // 定义数据列数据类型 Type dataType = typeof(string); // 获取对象成员 MemberInfo membeInfo = item.Value; // 判断对象成员是否是属性 if (membeInfo is PropertyInfo) { // 获取成员属性 PropertyInfo propertyInfo = membeInfo as PropertyInfo; // 设置数据列类型 dataType = propertyInfo.PropertyType; } else { // 获取成员字段 FieldInfo fieldInfo = membeInfo as FieldInfo; // 设置数据列类型 dataType = fieldInfo.FieldType; } // 判断数据类型是否是可空的泛型值类型 if (dataType.IsGenericType && dataType.GetGenericTypeDefinition() == typeof(Nullable<>)) { // 取出可空泛型值类型中的基础值类型 dataType = Nullable.GetUnderlyingType(dataType); } // 设置数据列数据类型 dataColumn.DataType = dataType; } // 遍历对象数组,转换对象为数据行 foreach (object obj in objs) { // 创建数据行数据链表 List<object> values = new List<object>(); // 遍历要转换的对象成员字典,转换成员数据 foreach (KeyValuePair<string, MemberInfo> item in memberInfos) { // 定义成员数据 object value = null; // 获取对象成员 MemberInfo membeInfo = item.Value; // 判断对象成员是否是属性 if (membeInfo is PropertyInfo) { // 获取成员属性 PropertyInfo propertyInfo = membeInfo as PropertyInfo; // 获取当前成员属性的GET访问器 MethodInfo methodInfo = propertyInfo.GetGetMethod(); // 判断当前成员属性的GET访问器是否是静态的 if (methodInfo.IsStatic) { // 获取成员属性的静态值 value = propertyInfo.GetValue(null, null); } else { // 获取成员属性的实例值 value = propertyInfo.GetValue(obj, null); } } else { // 获取成员字段 FieldInfo fieldInfo = membeInfo as FieldInfo; // 判断当前成员字段是否是静态的 if (fieldInfo.IsStatic) { // 获取成员字段的静态值 value = fieldInfo.GetValue(null); } else { // 获取成员字段的实例值 value = fieldInfo.GetValue(obj); } } // 添加成员数据到数据行数据链表中 values.Add(value); } // 添加数据行 dataTable.Rows.Add(values.ToArray()); } // 返回数据表 return dataTable; }
二、将DataTable转换为Array:
/// <summary> /// 转换数据表为对象数组 /// </summary> /// <param name="type">对象类型</param> /// <param name="dataTable">数据表</param> /// <param name="members">需要转换的成员</param> /// <param name="ignoreMembers">忽略转换的成员</param> /// <returns>返回对象数组</returns> public virtual object[] ConvertTable(Type type, DataTable dataTable, string[] members, string[] ignoreMembers) { // 创建目标对象数组 object[] objs = Array.CreateInstance(type, dataTable.Rows.Count) as object[]; // 创建要转换的对象成员字典 Dictionary<string, MemberInfo> memberInfos = new Dictionary<string, MemberInfo>(); // 遍历数据表中所有列,添加要转换的对象成员到字典中 foreach (DataColumn dataColumn in dataTable.Columns) { // 获取列名 string name = dataColumn.ColumnName; // 判断当前列是否需要转换 if ((members == null || members.Length <= 0 || members.Contains("*") || members.Contains(name)) && (ignoreMembers == null || ignoreMembers.Length <= 0 || (!ignoreMembers.Contains("*") && !ignoreMembers.Contains(name)))) { // 根据当前列名获取成员属性 PropertyInfo propertyInfo = type.GetProperty(name); // 判断是否有对应名称的成员属性 if (propertyInfo == null) { // 根据当前列名获取成员字段 FieldInfo fieldInfo = type.GetField(name); // 判断成员字段是否存在并且是否是公开可写的 if (fieldInfo != null && fieldInfo.IsPublic && !fieldInfo.IsLiteral && !fieldInfo.IsInitOnly) { // 添加要转换的对象成员 memberInfos[name] = fieldInfo; } } else { // 判断成员属性是否可写 if (propertyInfo.CanWrite) { // 获取成员属性的SET访问器 MethodInfo methodInfo = propertyInfo.GetSetMethod(); // 判断成员属性的SET访问器是否是公开的 if (methodInfo.IsPublic) { // 添加要转换的对象成员 memberInfos[name] = propertyInfo; } } } } } // 遍历转换数据表中的所有行 for (int i = 0, length = dataTable.Rows.Count; i < length; i++) { // 获取对应索引的数据行 DataRow dataRow = dataTable.Rows[i]; // 根据对象类型创建目标对象 object obj = Activator.CreateInstance(type); // 遍历要转换的对象成员字典,转换成员数据 foreach (KeyValuePair<string, MemberInfo> item in memberInfos) { // 获取当前行对应当前列的数据 object value = dataRow[item.Key]; // 获取对象成员 MemberInfo membeInfo = item.Value; // 判断对象成员是否是属性 if (membeInfo is PropertyInfo) { // 获取成员属性 PropertyInfo propertyInfo = membeInfo as PropertyInfo; // 根据成员属性类型转换数据类型 value = this.ConvertType(value, propertyInfo.PropertyType); // 判断数据转换是否成功 if (value != null) { // 获取成员属性的SET访问器 MethodInfo methodInfo = propertyInfo.GetSetMethod(); // 判断成员属性的SET访问器是否是静态的 if (methodInfo.IsStatic) { // 设置成员属性的静态值 propertyInfo.SetValue(null, value, null); } else { // 设置成员属性的实例值 propertyInfo.SetValue(obj, value, null); } } } else { // 获取成员字段 FieldInfo fieldInfo = membeInfo as FieldInfo; // 根据成员字段类型转换数据类型 value = this.ConvertType(value, fieldInfo.FieldType); // 判断数据转换是否成功 if (value != null) { // 判断成员字段是否是静态的 if (fieldInfo.IsStatic) { // 设置成员字段的静态值 fieldInfo.SetValue(null, value); } else { // 设置成员字段的实例值 fieldInfo.SetValue(obj, value); } } } } // 设置目标对象到对象数组中 objs[i] = obj; } // 返回目标对象数组 return objs; }