Schileru
Schileru

Reputation: 325

Getting property values of list of child objects

Let's say I have a Car class with some properties. One of the properties is an IEnumerable of another class, Passenger, with it's own properties.

public class Car
{
   public string Engine { get; set; }
   public int Wheels { get; set; }
   public IEnumerable<Passenger> Passengers { get; set }
}

I am able to get the values of the Engine and Wheels properties (and all others such properties). However, I can't figure out how to get the properties of all the Passenger objects. Here's what I'm doing to get the property values of a Car object:

Type type = car.GetType();
PropertyInfo[] properties = type.GetProperties();

foreach (PropertyInfo property in properties)
{
   object carValue = property.GetValue(car, null); 
   Console.WriteLine(carValue.ToString());
}

This obviously doesn't give me the Passenger properties, but outputs something like this instead:

System.Collections.GenericList'1[Passenger]

How do I grab all the property values of every Passenger in the car.Passengers list?

Upvotes: 1

Views: 3504

Answers (2)

Bhushan Firake
Bhushan Firake

Reputation: 9448

You will have to check whether the property of Car is an IEnumerable first and if it is, then you will have to again use reflection on it. this can better be done using recursion as below:

Your Car Object:

public class Car
    {
        public string Engine { get; set; }
        public int Wheels { get; set; }
        public IEnumerable<Passenger> Passengers { get; set; }
    }

Sample Application:

    internal class Program
    {
        private static void Main(string[] args)
        {
            var car = new Car
            {
                Engine = "1234",
                Wheels = 4,
                Passengers = new List<Passenger>
                {
                    new Passenger
                    {
                        Id = 1,
                        Name = "Bhushan"
                    }
                }
            };

            ReflectObject(car);
            Console.ReadKey();
        }

Functions Used:

        private static void ReflectObject(object objectToReflect)
        {
            foreach (var propertyInfo in objectToReflect.GetType().GetProperties())
            {
                object propertyValue = propertyInfo.GetValue(objectToReflect, null);
                if (IsEnumerable(propertyInfo))
                {
                    foreach (object obj in (IEnumerable)propertyValue)
                    {
                        ReflectObject(obj);
                    }
                }
                else
                {
                    Console.WriteLine(propertyValue);
                }
            }
        }

        private static bool IsEnumerable(PropertyInfo propertyInfo)
        {
            return propertyInfo.PropertyType.IsGenericType &&
                     propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(IEnumerable<>);
        }
    }

Output:

1234

4

1

Bhushan

Upvotes: 1

RePierre
RePierre

Reputation: 9566

You can do that with a mix of Type.IsGenericType and Type.GetGenericTypeDefinition().

private void DisplayObject(object obj)
{
    var type = obj.GetType();
    foreach(var propertyInfo in type.GetProperties())
    {
        object value = propertyInfo.GetValue(obj, null);
        if(propertyInfo.PropertyType.IsGenericType && 
            propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(IEnumerable<>))
        {
            foreach(object o in (IEnumerable)value)
            {
                DisplayObject(o);
            }
        }
        else
        {
            Console.WriteLine(value);
        }
    }
}

Upvotes: 3

Related Questions