如何用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
相关产品推荐
相关产品推荐

