views:

120

answers:

3

So for example:

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; }
}

but when i do this:

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;
}

the function returns

ChildProperty1
ChildProperty2
ParentProperty1
ParentProperty2
GrandProperty1
GrandProperty2

but I just need the properties up to the Parent class

ChildProperty1
ChildProperty2
ParentProperty1
ParentProperty2

Is there any possible way which we could specify how many levels of heirarchy could be used so the result returned would be as desired? Thanks in advance.

+2  A: 

No.

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

Add the above line, before result += prop.Name + "\n";

shahkalpesh
thanks! I really appreciate it!
ace
+1, exactly what i would have done.
slugster
+2  A: 

You can use BindingFlags.DeclaredOnly with Type.GetProperties to search only the properties declared on the Type and exclude properties that were inherited. Then you can write a method that gets the properties of a type and recursively its parent types for a specified recursion depth.

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;
}

Example:

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

Output:

ChildProperty1
ChildProperty2
ParentProperty1
ParentProperty2
dtb
i have tried that but to no avail...Thanks for the response. I appreciate it! =)
ace
You need to specify e.g. `BindingFlags.Public | BindingFlags.Instance` in addition to `BindingFlags.DeclaredOnly`.
Anton Tykhyy
@Anton Tykhyy: Didn't work either.
ace
@Anton: Fixed, thanks. Tested it now and it works.
dtb
A: 

I haven't tested it, but something like the following should do the trick.

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;
}
Dathan
Nice. I think you'll need change `type` somewhere in the loop though.
dtb
Thanks for pointing that out. I've added the "type=type.BaseType;" line, which should solve the problem.
Dathan