System.Reflection - 如何获取次级类型的PropertyInfo?

时间:2013-07-18 15:24:47

标签: c# .net system.reflection

我有三个课程如下:

public class TestA
{
    public string Str1 { get; set; }
    public string Str2 { get; set; }
    public List<TestB> LstTestBs { get; set; }
    public TestC ObjTestC { get; set; }
}

public class TestB
{
    public string Str3 { get; set; }
    public string Str4 { get; set; }
}

public class TestC
{
    public string Str5 { get; set; }
}

我试过了:

var prop = typeof (TestA).GetProperties();

但是,它只为TestA中的四个成员提供了PropertyInfo。我需要为TestA,TestB和TestC类中的所有成员获取PropertyInfo。

请帮忙...... 提前致谢, 圣

3 个答案:

答案 0 :(得分:0)

感谢大家的帮助。 我有答案。

        var prop = typeof (TestA).GetProperties();

        for (int i=0;i<prop.Count();i++)
        {
            var propertyInfo = prop[i];
            if (propertyInfo.PropertyType.Namespace != "System")
            {
                if (propertyInfo.PropertyType.IsGenericType &&
                    propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof (List<>))
                {
                    Type itemType = propertyInfo.PropertyType.GetGenericArguments()[0]; 
                    var listObjectProperties = itemType.GetProperties();
                    prop = prop.Union(listObjectProperties).ToArray();

                }
                else
                {

                    var childProp = propertyInfo.PropertyType.GetProperties();
                    prop = prop.Union(childProp).ToArray();
                }
            }
        }

答案 1 :(得分:0)

如果将所有类放在同一名称空间中,则可以通过枚举名称空间中的类来收集属性,而不是挖掘属性结构:

Getting all types in a namespace via reflection

答案 2 :(得分:0)

SLaks是对的。你应该递归地做这件事。有关该概念的更多信息,请参阅wikipedia's article on Recursion。例如,在您的情况下,这是一般的想法:

public void AddPropertiesAndChildPropertiesToList(Type type, List<PropertyInfo> list)
{
    var properties = type.GetProperties();
    list.AddRange(properties);
    foreach (var property in properties)
    {
        // recursive methods are ones that call themselves, like this...
        AddPropertiesAndChildPropertiesToList(property.PropertyType, list);
    }
}

请注意,此示例缺少一些内容:

  • 最重要的是,它无法防范无限递归。您可以通过使用Stack<Type> alreadyVisited参数跟踪已经存在的位置来解决此问题。如果您发现已经要求您添加已访问过的类型的属性列表,请改为使用该方法return,或者抛出异常。
  • 正如我在other related question中提到的,为了您的目的,您确实需要跟踪属性链,而不仅仅是属性。 alreadyVisited堆栈在这里也很有用。
  • 它不会以任何有用的方式处理您的List<TestB>。为此,您可能需要确定该类型是否具有索引器,然后确定该索引器返回的类型的属性。