Thewads
Thewads

Reputation: 5053

Getting specific properties from an object child

Struggled to come up with a decent way to ask/title this question, but will try and illustrate it as best I can.

I am working with a data structure something like this:

public Foo
{
     public Bar Bar {get;set;}
}

public Bar
{
    public SubTypeA TypeA {get;set;}
    public SubTypeB TypeB {get;set;}
    ...
}

public SubTypeA
{
    public int Status {get;set;}
    ...
}

Note that I am unable to change the data structure for this.

There are many different types in the Bar class, which all have different properties within them, but common to all of them is the property of Status.

What I need to do, is given an object of type Foo, is record the statuses for every item in the Bar object within it. Not every SubType is going to have a value every time though, some could be null.

I can sort of manage it by using a recursive function like below to loop through all the properties. It isn't ideal though I don't think as the loop could get quite large as there could be a lot of properties on each SubType.

private void GetProperties(Type classType, object instance)
{
    foreach (PropertyInfo property in classType.GetProperties())
    {

        object value = property.GetValue(instance, null);
        if (value != null) 
        {
            if (property.Name == "Status")
            {
                Record(classType, value);
            }
            GetProperties(property.PropertyType, value);
        }
    }
}

Is this about the only approach that there is for such a problem?

EDIT: Going by the answer given by Selman22, I have come up with another issue wherein I am trying to create an anonymous object based on the status and name of object.

var z = instance.GetType()
            .GetProperties()
            .Select(x => new 
                { 
                    status = x.GetValue(instance).GetType().GetProperty("status").GetValue(x, null), 
                    name = x.Name 
                })
            .ToList();

This is throwing an error of Object does not match target type. when trying to retrieve the value. Is this possible in a 1 liner?

Upvotes: 1

Views: 1895

Answers (2)

Selman Genç
Selman Genç

Reputation: 101681

You can get all Status properties using LINQ instead of recursion:

var barInstance = typeof(Foo).GetProperty("Bar").GetValue(fooInstance);

var statusProperties = barInstance.GetType()
            .GetProperties()
            .Select(x => x.GetValue(barInstance).GetType().GetProperty("Status"));

Upvotes: 0

milagvoniduak
milagvoniduak

Reputation: 3254

Type class contains GetProperty(string name, BindingFlags method) that you can use to retrieve specific property. Instead of looping through every property use this method.

http://msdn.microsoft.com/en-us/library/system.type.getproperty(v=vs.110).aspx

// Get Type object of MyClass.
Type myType=typeof(MyClass);       
// Get the PropertyInfo by passing the property name and specifying the BindingFlags.
PropertyInfo myPropInfo = myType.GetProperty("MyProperty", BindingFlags.Public | BindingFlags.Instance);

Upvotes: 2

Related Questions