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.