好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

?C# List 转换为 DataTable 的实现方法?

?C# List 转换为 DataTable 的实现方法?

以下提供两种常用方式将 List<T> 转换为 DataTable,支持泛型对象自动映射列,并处理空值和类型匹配问题。

?方法一:反射动态映射(通用型)?

通过反射自动提取对象属性作为 DataTable 的列,适用于任意类型的 List<T>。

using System.Reflection;

public static DataTable ListToDataTable<T>(List<T> list)

{

    DataTable dt = new DataTable();

    if (list == null || list.Count == 0)

        return dt; // 处理空列表

    // 获取对象属性作为列

    PropertyInfo[] props = typeof(T).GetProperties();

    foreach (PropertyInfo prop in props)

    {

        // 设置列名和数据类型(处理可空类型)

        Type colType = Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType;

        dt.Columns.Add(prop.Name, colType);

    }

    // 填充数据行

    foreach (T item in list)

    {

        DataRow row = dt.NewRow();

        foreach (PropertyInfo prop in props)

        {

            object value = prop.GetValue(item, null) ?? DBNull.Value;

            row[prop.Name] = value;

        }

        dt.Rows.Add(row);

    }

    return dt;

}

?方法二:手动映射(高性能)?

针对特定类型手动定义列,避免反射性能损耗,适合固定数据结构的场景。

public static DataTable ListToDataTableManual(List<Person> persons)

{

    DataTable dt = new DataTable();

    // 手动定义列

    dt.Columns.Add("Id", typeof(int));

    dt.Columns.Add("Name", typeof(string));

    dt.Columns.Add("BirthDate", typeof(DateTime));

    // 填充数据行

    foreach (Person person in persons)

    {

        DataRow row = dt.NewRow();

        row["Id"] = person.Id;

        row["Name"] = person.Name ?? string.Empty; // 处理空值

        row["BirthDate"] = person.BirthDate.HasValue ? 

            person.BirthDate.Value : (object)DBNull.Value;

        dt.Rows.Add(row);

    }

    return dt;

}

?使用示例?

?定义实体类?

public class Person

{

    public int Id { get; set; }

    public string Name { get; set; }

    public DateTime? BirthDate { get; set; } // 可空类型

}

?转换并绑定到 DataGridView?

csharp

Copy Code

List<Person> people = new List<Person>

{

    new Person { Id = 1, Name = "张三", BirthDate = new DateTime(1990, 5, 1) },

    new Person { Id = 2, Name = "李四", BirthDate = null }

};

// 使用反射方法转换

DataTable dt = ListToDataTable(people);

// 绑定到 DataGridView

dataGridView1.DataSource = dt;

?关键点说明?

?特性? ?反射方法? ?手动方法?

?通用性? 支持任意 List<T> 仅限预定义类型

?性能? 反射有性能损耗,适用于数据量小或低频操作 高性能,适合大数据量或高频调用

?可维护性? 自动适应属性变化(如新增字段) 需手动维护列映射

?空值处理? 自动将 null 转换为 DBNull.Value 需显式处理可空字段

?扩展优化?

?缓存反射结果?:

若频繁转换同一类型,可缓存 PropertyInfo 数组提升性能。

private static Dictionary<Type, PropertyInfo[]> _propertyCache = new Dictionary<Type, PropertyInfo[]>();

?忽略特定属性?:

通过 Attribute 标记需要跳过的字段。

if (prop.GetCustomAttribute<IgnoreColumnAttribute>() != null)

    continue;

?自定义列名?:

使用 [DisplayName("列名")] 特性覆盖默认属性名。

string columnName = prop.GetCustomAttribute<DisplayNameAttribute>()?.DisplayName ?? prop.Name;

dt.Columns.Add(columnName, colType);

?常见问题解决?

?类型不匹配错误?

确保 DataColumn 类型与属性实际类型一致(如 int? 映射为 typeof(int))。

使用 Nullable.GetUnderlyingType 处理可空类型。

?空引用异常?

在访问属性值前检查对象是否为 null。

使用 ?? 运算符提供默认值。

?性能优化?

对大规模数据使用 手动映射 或 Emit 动态生成IL代码(高级技巧)。

通过上述方法,可灵活实现 List<T> 到 DataTable 的转换,满足通用性或高性能需求。


查看更多关于?C# List 转换为 DataTable 的实现方法?的详细内容...

  阅读:25次