4

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.

1 Answer 1

11

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.

Sign up to request clarification or add additional context in comments.

6 Comments

Why not just return items.Cast<T>().ToList();?
@bmused That only works when the all objects are of a type T. It's basically a box / un-box. In my example using integers as input, .Cast<string> and .Cast<double> would fail.
If the type is only known at runtime above approach won't work
@BrokenGlass See my updated answer for a solution that work when the type is only known at run-time.
I was looking for the last option you gave me. Awesome answer! I presume I could do a similar (but perhaps more complex) version of this to convert Arrays or Dictionaries from one type to another?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.