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

使用反射获取类的所有属性及子属性时遇递归问题求助

解决反射递归获取属性时的列表归属问题

我懂你现在的困扰——递归遍历嵌套属性的时候,子成员总是跑到错误的列表里,导致整个结构乱掉对吧?看你贴的代码片段,应该是递归调用GetMembers时没有把子属性正确关联到父成员的子集合里,而是一股脑加到了顶层列表或者某个共用的子列表中。

先明确核心前提

你的Member类应该需要一个存放子成员的属性,不然没法区分层级,比如:

public class Member
{
    public string Name { get; set; }
    public object Value { get; set; }
    public List<Member> ChildMembers { get; set; } = new List<Member>(); // 关键:子成员专属容器
}

之前的代码里,你可能把递归获取到的子成员都塞到了同一个childMembers列表,没有绑定到当前遍历的父member上,自然会出现层级混乱的问题。

修正后的递归实现

下面是调整后的代码,重点解决递归时的列表归属问题,同时处理了值类型、字符串和循环引用的边界情况:

private List<Member> GetMembers(object instance, HashSet<object> processedObjects = null)
{
    var memberList = new List<Member>();
    // 初始化已处理对象集合,防止循环引用导致栈溢出
    processedObjects ??= new HashSet<object>();
    
    // 边界处理:值类型、字符串、null或已处理过的对象,直接返回空列表(按需调整)
    if (instance == null || instance.GetType().IsValueType || instance is string || processedObjects.Contains(instance))
    {
        return memberList;
    }
    
    processedObjects.Add(instance);
    var type = instance.GetType();

    foreach (var propertyInfo in type.GetProperties(BindingFlags.Public | BindingFlags.Instance))
    {
        // 跳过索引器属性(比如this[int index]这类)
        if (propertyInfo.GetIndexParameters().Length > 0)
            continue;
            
        var member = new Member
        {
            Name = propertyInfo.Name,
            Value = propertyInfo.GetValue(instance)
        };
        
        // 核心:递归获取当前属性的子成员,直接绑定到当前member的ChildMembers
        var childMembers = GetMembers(member.Value, processedObjects);
        member.ChildMembers.AddRange(childMembers);
        
        memberList.Add(member);
    }
    
    return memberList;
}

关键调整点

  • 子成员归属正确:递归得到的子成员直接添加到当前member的ChildMembers,而不是共用的列表,保证层级结构清晰。
  • 循环引用防护:用HashSet<object>跟踪已经处理过的对象,避免对象互相引用导致无限递归栈溢出。
  • 边界类型过滤:跳过值类型、字符串和null,因为这些没有子属性可遍历。
  • 排除索引器:去掉类里的索引器属性,避免不必要的无效遍历。

调用示例验证

假设你有这样的嵌套类:

public class Address
{
    public string Street { get; set; }
    public string City { get; set; }
}

public class User
{
    public string Name { get; set; }
    public int Age { get; set; }
    public Address HomeAddress { get; set; }
}

调用GetMembers(new User { Name = "John", Age = 30, HomeAddress = new Address { Street = "Main St", City = "NY" } }),就能得到正确的层级结构:

  • User
    • Name: "John"
    • Age: 30
    • HomeAddress
      • Street: "Main St"
      • City: "NY"

这样就不会出现子成员跑到错误列表的问题啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:43:29