Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 603
Anthony Main Avatar asked Sep 10 '09 16:09

Anthony Main


1 Answers

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 });
}
like image 58
Jon Skeet Avatar answered Oct 16 '22 04:10

Jon Skeet