You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

泛型<T>函数无法获取继承类字段?DataTable转List反射问题

问题原因与解决方法

核心原因

你代码里调用的typeof(T).GetProperties()只能获取类的属性(Property),而FooChild中的IsFoo是字段(Field)——这是.NET反射里两个完全不同的成员类型,所以不管加什么BindingFlags,GetProperties()都不会读取字段,自然拿不到IsFoo的信息。

解决方法

方案1:将字段改为属性(推荐)

遵循.NET编码规范,把FooChild里的字段改成自动属性,原转换函数无需修改即可正常获取该成员:

public class FooChild : Foo
{
    public bool IsFoo { get; set; } // 替换原来的public bool IsFoo;
}

方案2:修改转换函数,同时支持属性和字段

如果必须保留字段,需在反射逻辑中同时获取属性和字段,统一处理映射:

public static List<T> ConvertToList<T> (DataTable dt)
{
    List<string> columnNames = dt.Columns.Cast<DataColumn>().Select(c => c.ColumnName.ToLower()).ToList();
    // 获取所有公共实例属性
    var properties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
    // 获取所有公共实例字段
    var fields = typeof(T).GetFields(BindingFlags.Public | BindingFlags.Instance);

    // 统一整理可赋值的成员(名称+赋值方法)
    var assignableMembers = new List<(string LowerName, Action<T, object> SetValue)>();

    // 处理属性
    foreach (var prop in properties)
    {
        string lowerName = prop.Name.ToLower();
        if (columnNames.Contains(lowerName))
        {
            assignableMembers.Add((lowerName, (obj, val) => prop.SetValue(obj, val)));
        }
    }

    // 处理字段
    foreach (var field in fields)
    {
        string lowerName = field.Name.ToLower();
        if (columnNames.Contains(lowerName))
        {
            assignableMembers.Add((lowerName, (obj, val) => field.SetValue(obj, val)));
        }
    }

    // 转换DataTable到List<T>的核心逻辑
    var result = new List<T>();
    foreach (DataRow row in dt.Rows)
    {
        T item = Activator.CreateInstance<T>();
        foreach (var member in assignableMembers)
        {
            object value = row[member.LowerName];
            if (value != DBNull.Value)
            {
                member.SetValue(item, value);
            }
        }
        result.Add(item);
    }
    return result;
}

注意事项

  • 字段(Field)是类直接声明的变量,属性(Property)是封装字段的访问器(带get/set),两者在反射中是分开处理的。
  • 优先使用属性,因为它符合面向对象的封装原则,能更好地控制成员的访问逻辑。

内容的提问来源于stack exchange,提问作者Rikube

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 22:50:23