Генери c Список <T>как кастовать? - PullRequest
0 голосов
/ 11 января 2020

У меня есть метод, который читает, какой тип элемента из файла xml. Этот процесс происходит в методе "AnalyzeNodeLabel ()". Затем в этом методе они сохраняются в списках, либо в одном из classObjects, либо в одном из interfaceObjects. По типу он должен добавить его в список.

Мой код:

        List<T> getModel<T>(XmlReader reader, List<string> id) where T : BaseObject
        {

            List<ClassObject> classModels = new List<ClassObject>();
            List<InterfaceObject> interfaceModels = new List<InterfaceObject>();

            while (reader.Read())
            {
                if (id != null)
                {
                    foreach (var item in id)
                    {
                        var baseModel = AnalyzeNodeLabel<BaseObject>(reader, item);
                        if (baseModel.GetType() == typeof(ClassObject))
                        {
                            classModels.Add((ClassObject)baseModel);
                            return (T)Convert.ChangeType(classModels,typeof(List<ClassObject>));
                        }
                        if (baseModel.GetType() == typeof(InterfaceObject))
                        {
                            interfaceModels.Add((InterfaceObject)baseModel);
                            return (T)Convert.ChangeType(interfaceModels,typeof(List<InterfaceObject>));
                        } 
                    }
                }
            }
            return null;
        }

Но у меня возникают проблемы с конвертацией. при возврате (T) конвертировать ... заявления. Список неявно не конвертируется в Список ...

Ответы [ 2 ]

1 голос
/ 12 января 2020

Вы не можете преобразовать List<Child> children в List<Base> bases

Причина в том, что если компилятор разрешит вам это безопасно сделать. Вот почему

class Base {}
class Child1 : Base {}
class Child2 : Base {}

var children = new List<Child1>();
var bases = (List<Base>)children; // Let's assume this is acceptable

bases.Add(new Child2());          // Now this will add an instance of Child2
                                  // to a List<Child1> which should not be possible

Если вы планируете читать только с children, вы можете безопасно преобразовать его в IReadOnlyList<Base>. Это безопасно, так как IReadOnlyList<> интерфейс не допускает модификации. Подробнее об этом см. .

В качестве альтернативы, если вам нужен список базового класса , вы можете создать новый List<Base> из List<Child1>, используя Cast и ToList методы расширения:

using System.Linq;
...

Base[] bases = children.Cast<Base>().ToList();

1 голос
/ 11 января 2020

Вы не можете напрямую привести List<A> к List<a>, где a:A из-за ковариации (потому что typeof(List<A>) не наследуется от typeof(List<a>).

Однако есть linq Cast метод.

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