Reputation: 5053
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
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
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