Anthony Main
Anthony Main

Reputation: 6068

How can I perform a List<object>.Cast<T> using reflection when T is unknown

I've been trying to do this for a good few hours now and this is as far as I have got

var castItems = typeof(Enumerable).GetMethod("Cast")
                  .MakeGenericMethod(new Type[] { targetType })
                  .Invoke(null, new object[] { items });

This returns me

System.Linq.Enumerable+d__aa`1[MyObjectType]

whereas I need (for my ViewData) as generic list i.e.

System.Collections.Generic.List`1[MyObjectType]

Any pointers would be great

Upvotes: 12

Views: 4553

Answers (1)

Jon Skeet
Jon Skeet

Reputation: 1503479

You just need to call ToList() on it afterwards:

static readonly MethodInfo CastMethod = typeof(Enumerable).GetMethod("Cast");
static readonly MethodInfo ToListMethod = typeof(Enumerable).GetMethod("ToList");

...

var castItems = CastMethod.MakeGenericMethod(new Type[] { targetType })
                          .Invoke(null, new object[] { items });
var list = ToListMethod.MakeGenericMethod(new Type[] { targetType })
                          .Invoke(null, new object[] { castItems });

Another option would be to write a single generic method in your own class to do this, and call that with reflection:

private static List<T> CastAndList(IEnumerable items)
{
    return items.Cast<T>().ToList();
}

private static readonly MethodInfo CastAndListMethod = 
    typeof(YourType).GetMethod("CastAndList", 
                               BindingFlags.Static | BindingFlags.NonPublic);

public static object CastAndList(object items, Type targetType)
{
    return CastAndListMethod.MakeGenericMethod(new[] { targetType })
                            .Invoke(null, new[] { items });
}

Upvotes: 20

Related Questions