一、将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;
}