【问题标题】:How to get the properties of a class using reflection (specifying how many levels of hierarchy) in C#.Net?如何在 C#.Net 中使用反射(指定多少层次的层次结构)获取类的属性?
【发布时间】:2010-12-18 23:14:42
【问题描述】:

例如:

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

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

【问题讨论】:

  • 不是开箱即用的。不过,您可以编写一些自定义的东西来做到这一点。
  • 不要在循环中使用字符串连接。
  • @Dmitriy Matveev:这只是为了测试结果。 =)
  • 现在,我遇到了另一个问题...如果我不进行字符串连接,那么我可能需要将项目添加到通用列表中...我稍后会尝试解决这个问题。

标签: c# inheritance reflection properties


【解决方案1】:

您可以使用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));

输出:

子属性1 ChildProperty2 父属性 1 父属性 2

【讨论】:

  • 我已经尝试过了,但无济于事......感谢您的回复。我很感激! =)
  • 您需要指定例如BindingFlags.Public | BindingFlags.Instance 除了BindingFlags.DeclaredOnly
  • 如果我只有一个具有完整类名的字符串,以及像 MyNameSpace1.X.Y.Z.ClassName 和 PropertyName 这样的属性名称?
【解决方案2】:

没有。

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

result += prop.Name + "\n";之前添加上述行

【讨论】:

    【解决方案3】:

    我还没有测试过,但是类似下面的东西应该可以解决问题。

    IEnumerable GetProperties(Type t, int depth)
    {
      列表 属性 = 新列表();
      如果(类型!= null)
      {
        而(深度-> 0)
        {
          properties.AddRange(type.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance) ;
          类型 = 类型.BaseType;
        }
      }
      返回属性;
    }

    【讨论】:

    • 不错。我认为你需要在循环中的某处更改type
    • 感谢您指出这一点。我添加了“type=type.BaseType;”行,应该可以解决问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-11
    相关资源
    最近更新 更多