如何在C#.Net中使用反射(指定多少级别的层次结构)来获取类的属性?

时间:2009-11-21 03:51:25

标签: c# inheritance reflection properties

例如:

class GrandParent {
    public int GrandProperty1 { get; set; }
    public int GrandProperty2 { get; set; }
}

class Parent : GrandParent {
    public int ParentProperty1 { get; set; }
    public int ParentProperty2 { get; set; }
    protected int ParentPropertyProtected1 { get; set; }
}

class Child : Parent {
    public int ChildProperty1 { get; set; }
    public int ChildProperty2 { get; set; }
    protected int ChildPropertyProtected1 { get; set; }
}

但是当我这样做时:

public String GetProperties() {
    String result = "";
    Child child = new Child();
    Type type = child.GetType();
    PropertyInfo[] pi = type.GetProperties();
    foreach (PropertyInfo prop in pi) {
        result += prop.Name + "\n";
    }
    return result;
}

函数返回

ChildProperty1
ChildProperty2
ParentProperty1
ParentProperty2
GrandProperty1
GrandProperty2

但我只需要属于父类的属性

ChildProperty1
ChildProperty2
ParentProperty1
ParentProperty2

是否有任何可能的方法可以指定可以使用多少级别的层次结构,以便返回的结果符合要求?提前谢谢。

3 个答案:

答案 0 :(得分:4)

没有

if (prop.DeclaringType == typeof(Child) || 
prop.DeclaringType == typeof(Child).BaseType)

result += prop.Name + "\n";

之前添加上述行

答案 1 :(得分:4)

您可以将BindingFlags.DeclaredOnlyType.GetProperties一起使用,仅搜索在Type上声明的属性,并排除已继承的属性。然后,您可以编写一个方法来获取类型的属性,并递归地获取指定递归深度的父类型。

string GetProperties(Type type, int depth)
{
    if (type != null && depth > 0)
    {
        string result = string.Empty;
        PropertyInfo[] pi = type.GetProperties(BindingFlags.DeclaredOnly |
            BindingFlags.Public | BindingFlags.Instance);
        foreach (PropertyInfo prop in pi)
        {
            result += prop.Name + "\n";
        }
        result += GetProperties(type.BaseType, depth - 1) + "\n";
        return result;
    }

    return null;
}

示例:

Console.WriteLine(GetProperties(typeof(Child), 2));

输出:

ChildProperty1
ChildProperty2
ParentProperty1
ParentProperty2

答案 2 :(得分:0)

我还没有测试过,但是下面的内容应该可以解决问题。

IEnumerable<PropertyInfo> GetProperties(Type t, int depth)
{
  List<PropertyInfo> properties = new List<PropertyInfo>();
  if (type != null)
  {
    while (depth-- > 0)
    {
      properties.AddRange(type.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance) ;
      type = type.BaseType;
    }
  }
  return properties;
}