简体   繁体   中英

C# Convert array to generic T List<>

I'm trying to convert an array (object[]) to a generic type T where T is a List<>

The issue here is that T is the type of the list and not the type of the items in the list. So we can't just create a List.

While I could serialize the array and deserialize it into a generic T, I don't want to use this option and would favor a faster approach to the problem.

Below is the code to test and reproduce the issue.

public T ConvertList<T>(object obj)
{

    if (obj is object[] objects)
    {
        var type = objects.GetType().GetElementType();
        var list = objects.Select(o => Convert.ChangeType(o, type)).ToList();

        // Unable to cast object of type 'System.Collections.Generic.List`1[System.Object]' to type 'System.Collections.Generic.List`1[System.String]'.'
        return (T)(object)list;
    }

    return default;

}

var list = ConvertList<List<string>>( new []{ "1", "a", "b" });
Assert.AreEqual(typeof(List<string>), list.GetType());

The issue here is that we cannot do something like:

var list = new List<typeof(type)>()

I'm open to suggestions on how we can achieve something like this.

Thanks.

To solve this problem we can use the fact that generic class List<TElement> implements non-generic interface IList . Here is how we can use this fact to solve your problem:

public T ConvertList<T>(object obj)
{
    if (obj is object[] objects)
    {
        // Here we create an instance of type T, where T is actually a generic
        // List<TElement>. Then we cast it to type IList. Therefore here we don't 
        // have to know and specify the type of the elements of List<TElement>.
        IList list = (IList) Activator.CreateInstance(typeof(T));

        foreach (object o in objects)
            // Here we call IList.Add(object o). Internally it casts added
            // elements to the actual type of the elements of List<TElement>.
            list.Add(o);

        return (T) list;
    }

    return default;
}

Here is complete sample that shows this approach.

To use this approach you should ensure that a correct type of the List<TElement> is specified when calling method ConvertList<T> .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM