Question

I'm using reflection to get all properties of a specific object and iterate over them.

I'm calling these properties props.

When those are non-List objects, this all works fine.

I need a way to know when a prop I'm iterating over is a list (I saw there is a prop.PropertyType.IsArray for instance, but not one for list).

I saw here Determine if a property is a kind of array by reflection that they suggested to use:

property.PropertyType.GetInterface(typeof(IEnumerable<>).FullName) != null

But this is not good enough for me since string implements that as well.

(Right now I'm checking that prop.Namespace contains "collection" in it, obviously looking for a better way).

After I've done that, I have a working assumption that the List will be a List of a complex object. (but could be one of several complex ojects so I don't know which)

The harder part is that I need to iterate over those objects and get their members as well, but have failed to do so.

So if I have List<TestObject> as my prop I need to have a foreach (TestObject testObj in prop) somehow (in concept).

Don't have a reasonable attempt to show here, since I haven't yet figured out a way to treat prop as a List of my complex object and iterate over it.

EDIT: I've managed to get the value with prop.GetValue(reflectedObject) but I have to cast that to List<MyComplexObject>

No correct solution

OTHER TIPS

I think looking into this code sample can help.

public class MyClass
{
    public string Name { get; set; }
    public int Id { get; set; }
    public List<int> Subordinates { get; set; }
}

Use MyClass:

var myClass = new MyClass
{
    Id = 1,
    Name = "My Name",
    Subordinates = new List<int> { 2, 5, 8 }
};

var props = myClass.GetType().GetProperties();
foreach (var info in props)
{
    var type = info.PropertyType;

    if (type.IsGenericType && (type.GetGenericTypeDefinition() == typeof(List<>)))
    {
        foreach (var listitem in info.GetValue(myClass, null) as IEnumerable)
        {
            Console.WriteLine("Item: " + listitem.ToString());
        }

        continue;
    }
    Console.WriteLine(info.GetValue(myClass, null));
}

I think that working with the IEnumerable<> interface is actually the way forward. Do you have some sort of a base type for your objects? If yes, then you can work around the issue with string be looking for collections of objects that extend the base type. If no, then you can treat strings as a special case before you check for the IEnumerable<> interface.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top