【问题标题】:Reflection: Get all subproperties反射:获取所有子属性
【发布时间】:2015-05-07 08:43:17
【问题描述】:

我有一个包含对象的列表,每个对象都包含多种类型的许多属性,每个属性还包含子属性。

我需要通过反射获取所有属性并将它们存储在一个 PropertyInfo[] ...

这甚至可以通过反射实现吗?我真的需要通过反射来做到这一点......

【问题讨论】:

  • P.S. : 我不知道对象在编码过程中包含多少子属性,总是不同的
  • 请阅读文章How to Ask ...您尝试了什么? (简短但完整的示例)示例数据结构和预期结果也有很大帮助
  • 那么周期呢?很容易进入属性的无限循环。你真正想解决什么问题?

标签: c# reflection propertyinfo


【解决方案1】:

没有“子属性”之类的东西 - 属性属于某种类型,可以具有某种类型的值(即属性类型的子类),并且该类型可以具有自己的属性。

您可以为此使用递归:

List<PropertyInfo> properties = new List<PropertyInfo>();
foreach (object obj in myList)
{
    properties.AddRange(GetDeepProperties(obj, ...));
}

PropertyInfo[] array = properties.ToArray();

...

IEnumerable<PropertyInfo> GetDeepProperties(object obj, BindingFlags flags)
{
    // Get properties of the current object
    foreach (PropertyInfo property in obj.GetType().GetProperties(flags))
    {
        yield return property;

        object propertyValue = property.GetValue(obj, null);
        if (propertyValue == null)
        {
            // Property is null, but can still get properties of the PropertyType
            foreach (PropertyInfo subProperty in property.PropertyType.GetProperties(flags))
            {
                yield return subProperty;
            }
        }
        else
        {
            // Get properties of the value assiged to the property
            foreach (PropertyInfo subProperty = GetDeepProperties(propertyValue))
            {
                yield return subProperty;
            }
        }
    }
}

上面的代码只是一个例子:

  • 我没有尝试甚至编译它
  • 如果此“属性树”中的某处对象相互指向,您将获得 StackOverflowException
  • 它错过了 null 检查和异常处理(属性 getter 可以抛出异常)
  • 它忽略了索引属性的存在

我不知道你想用这个数组做什么 - 对创建每个 PropertyInfo 的对象的引用丢失了,所以你不能再获取或设置它们的值。

【讨论】:

    【解决方案2】:

    例子:

    class Program
    {
        static void Main(string[] args)
        {
            PropertyInfo[] result = GetAllPropertyInfos(typeof(Example)).ToArray(); ;
    
            foreach (string property in result.Select(p => string.Format("{0} : {1}",p.Name,p.PropertyType.Name)))
            {
                Console.WriteLine(property);
            }
    
        }
    
        static IEnumerable<PropertyInfo> GetAllPropertyInfos(Type type)
        {
            List<PropertyInfo> result = new List<PropertyInfo>();
            foreach (PropertyInfo propertyInfo in type.GetProperties())
            {
                result.Add(propertyInfo);
                result.AddRange(GetAllPropertyInfos(propertyInfo.PropertyType));
            }
            return result;
        }
    }
    
    class Example
    {
        public AnotherExample AProperty { get; set; }
        public int AnotherProperty { get; set; }
    }
    
    class AnotherExample
    {
        public int YetAnotherProperty { get; set; }
    }
    

    输出:

    AProperty : AnotherExample
    YetAnotherProperty : Int32
    AnotherProperty : Int32
    

    【讨论】:

      猜你喜欢
      • 2014-08-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-24
      • 1970-01-01
      • 2017-05-14
      • 2011-02-15
      • 1970-01-01
      相关资源
      最近更新 更多