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

如何用C#反射获取含自定义属性的嵌套对象所有属性信息?

实现带[Custom]属性的嵌套对象属性提取方法

首先需要补充定义你用到的CustomAttribute特性类,以及返回结果所需的PropInf类,再通过递归遍历实现核心提取逻辑:

1. 定义基础类型

using System;

// 自定义特性类
public class CustomAttribute : Attribute
{
}

// 结果实体类
public class PropInf
{
    public string PropertyName { get; set; }
    public object Value { get; set; }
    public string Route { get; set; }

    // 重写ToString方便查看输出
    public override string ToString()
    {
        return $"[PropertyName= {PropertyName},Value={Value} ,Route=\"{Route}\" ]";
    }
}

2. 核心提取工具类

using System;
using System.Collections.Generic;
using System.Reflection;

public static class PropertyExtractor
{
    // 对外暴露的入口方法
    public static List<PropInf> GetMyProperties(object obj)
    {
        return GetMyPropertiesRecursive(obj, string.Empty);
    }

    // 递归处理嵌套对象的私有方法
    private static List<PropInf> GetMyPropertiesRecursive(object obj, string currentRoute)
    {
        var result = new List<PropInf>();
        if (obj == null) return result;

        Type objType = obj.GetType();
        // 获取当前对象的所有公共实例属性
        PropertyInfo[] properties = objType.GetProperties(BindingFlags.Public | BindingFlags.Instance);

        foreach (PropertyInfo prop in properties)
        {
            // 检查属性是否带有[Custom]标记
            bool hasCustomAttr = Attribute.IsDefined(prop, typeof(CustomAttribute));
            // 构建当前属性的完整路由路径
            string propRoute = string.IsNullOrEmpty(currentRoute) ? prop.Name : $"{currentRoute}.{prop.Name}";

            if (hasCustomAttr)
            {
                // 提取带标记的属性信息
                object value = prop.GetValue(obj);
                result.Add(new PropInf
                {
                    PropertyName = prop.Name,
                    Value = value ?? "null",
                    Route = propRoute
                });
            }
            else
            {
                Type propType = prop.PropertyType;
                // 仅对非简单引用类型递归(排除值类型、string、枚举)
                if (!propType.IsValueType && propType != typeof(string) && !propType.IsEnum)
                {
                    object nestedObj = prop.GetValue(obj);
                    result.AddRange(GetMyPropertiesRecursive(nestedObj, propRoute));
                }
            }
        }

        return result;
    }
}

3. 测试验证

用你提供的测试实例调用方法:

SomeModel model = new SomeModel()
{
    Name = "farid",
    Surname = "Ismayilzada",
    TestData = "Test",
    InnerModel = new InnerModel() { Year = "2022", HidedObject = new ThirdObject{ HidedName="Secret"}}
};

List<PropInf> properties = PropertyExtractor.GetMyProperties(model);

// 输出结果
foreach (var prop in properties)
{
    Console.WriteLine(prop);
}

运行后会输出你期望的结果:

[PropertyName= Name,Value=farid ,Route="Name" ]
[PropertyName= Surname,Value=Ismayilzada,Route="Surname" ]
[PropertyName= Year,Value=2022,Route="InnerModel.Year" ]
[PropertyName= HidedName,Value=Secret,Route="InnerModel.HidedObject.HidedName" ]

关键逻辑说明

  • 递归遍历:通过私有递归方法处理嵌套对象,传递当前路径构建完整的Route
  • 特性检查:使用Attribute.IsDefined精准判断属性是否带有[Custom]标记
  • 类型过滤:仅对非简单引用类型递归,避免遍历值类型、字符串等无嵌套属性的类型
  • 空值处理:对属性值为null的情况做了兜底,防止空引用异常

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 17:36:09