Gerard
Gerard

Reputation: 2709

How to loop through a list of a generic type

I need to loop through a list where the type is not known at compile-time. How to do that? The following code fails at runtime, conversion not allowed:

    Type objType = dataObject.GetType();
    List<string> strList = new List<string>();

    foreach (PropertyInfo prop in objType.GetProperties())
    {
        var val = prop.GetValue(dataObject);

        if (prop.PropertyType.Name.StartsWith("List"))   // Is there a better way?
        {
            foreach (object lval in (List<object>) val)  // Runtime failure (conversion not allowed)
            {
                strList.Add(lval.ToString());
            }
        }
        ...

Upvotes: 4

Views: 8130

Answers (4)

Grundy
Grundy

Reputation: 13381

maybe it will be easier

 foreach (PropertyInfo prop in objType.GetProperties())
        {
            var val = prop.GetValue(x,null);

            if (typeof(IEnumerable).IsAssignableFrom(prop.PropertyType) && prop.PropertyType.IsGenericType)   // Is there a better way?
            {
                dynamic dd = val;
                foreach (object lval in dd)  
                {
                    strList.Add(lval.ToString());
                }
            }

Upvotes: 0

Janne Matikainen
Janne Matikainen

Reputation: 5121

foreach (var propInfo in foobar.GetType().GetProperties())
{
    var val = propInfo.GetValue(foobar, null);

    if (typeof(IEnumerable).IsAssignableFrom(propInfo.PropertyType))
    {
        var collectionItems = (IEnumerable)val;
        if (collectionItems != null)
        {
            foreach (object lval in collectionItems)
            {
                Console.WriteLine(lval);
            }
        }
    }
}

Upvotes: 0

dcastro
dcastro

Reputation: 68660

Just wanted to add something to what has already been said:

Your logic is flawed because List<int> (for example) is not a subclass of List<object>. List<T> is not covariant in its type parameter.

If it was, it would be legal to do this:

List<object> listOfObjects = new List<int>();
listOfObjects.Add("a string");

Read this to learn more about covariance/contravariance in C#:

http://blogs.msdn.com/b/csharpfaq/archive/2010/02/16/covariance-and-contravariance-faq.aspx

Upvotes: 1

Marc Gravell
Marc Gravell

Reputation: 1062810

If you don't know the type, then : generics may not be the best option:

IList list = val as IList; // note: non-generic; you could also
                           // use IEnumerable, but that has some
                           // edge-cases; IList is more predictable
if(list != null)
{
    foreach(object obj in list)
    {
        strList.Add(obj.ToString());
    }
}

Upvotes: 7

Related Questions