Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How To Cast Generic List of One Type To Generic List of an Unknown Type

I would like to write a function that takes a List<Object> and returns a the original list casted to a list of a specified object type List<ObjectType>, knowing that the objects within the original list are of type ObjectType. The trick is that ObjectType could be any type, which I find using Reflection. Sorry for the lack of code, but I have had no luck understanding how I might even go about doing this.

like image 449
Brad Ross Avatar asked Dec 25 '22 23:12

Brad Ross


1 Answers

If you know that each item in the list is of type ObjectType, you can do this:

List<object> sourceList = new List<object>() { 1, 2, 3 };
List<int> resultList = sourceList.Cast<int>().ToList();

If you actually want to convert each item in the list in a generic way, the simplest way would be to do something like this:

public static IEnumerable<T> ConvertTo<T>(this IEnumerable items)
{
    return items.Cast<object>().Select(x => (T)Convert.ChangeType(x, typeof(T)));
}

This would be implemented as an extension method, so you can write:

List<object> sourceList = new List<object>() { 1, 2, 3 };
List<string> resultList = sourceList.ConvertTo<string>().ToList();

If the target type isn't known at compile-time, you would indeed need to use reflection. Something like this would work:

class ListUtil
{
    public static List<T> ConvertToList<T>(this IEnumerable items)
    {
        // see method above
        return items.ConvertTo<T>().ToList();
    }

    public static IList ConvertToList(this IEnumerable items, Type targetType)
    {
        var method = typeof(ListUtil).GetMethod(
            "ConvertToList", 
            new[] { typeof(IEnumerable) });
        var generic = method.MakeGenericMethod(targetType);
        return (IList)generic.Invoke(null, new[] { items });
    }
}

And now you can call it like:

List<object> sourceList = new List<object>() { 1, 2, 3 };
IList resultList = ListUtil.ConvertToList(sourceList, typeof(string));
resultList.GetType(); // List<string>

Of course, you loose any compile-time type safety with this method.

like image 79
p.s.w.g Avatar answered Feb 15 '23 23:02

p.s.w.g