C# Преобразование массива в универсальный c T List <> - PullRequest
0 голосов
/ 24 апреля 2020

Я пытаюсь преобразовать массив (объект []) в общий c тип T, где T - это список <>

. Проблема в том, что T - это тип списка и не тип элементов в списке. Поэтому мы не можем просто создать список.

Хотя я мог бы сериализовать массив и десериализовать его в обобщенный c T, я не хочу использовать эту опцию и предпочел бы более быстрый подход к проблема.

Ниже приведен код для тестирования и воспроизведения проблемы.

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());

Проблема в том, что мы не можем сделать что-то вроде:

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

I ' Я открыт для предложений о том, как мы можем достичь чего-то подобного.

Спасибо.

1 Ответ

0 голосов
/ 26 апреля 2020

Для решения этой проблемы мы можем использовать тот факт, что generi c class List<TElement> реализует не-generi c интерфейс IList. Вот как мы можем использовать этот факт для решения вашей проблемы:

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;
}

Вот полный образец , который демонстрирует этот подход.

Чтобы использовать этот подход, вы должны убедиться, что что при вызове метода ConvertList<T>.

указан правильный тип List<TElement>.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...