Преобразование списка <object>в список <complex>, где complex - это определенный пользователем тип - PullRequest
2 голосов
/ 17 августа 2011

Допустим, у меня есть класс, как

public class Complex { } // this is what I mean when I say List<Complex>
// its just a user-defined class or type if you will

Теперь, допустим, у меня есть метод, который возвращает список, содержащий объекты.

Теперь, допустим, я могу дополнительно гарантировать, что каждый из этих объектов в списке на самом деле имеет тип Complex (другими словами, List )

Я бы хотел самый безболезненный способ составления этого списка, насколько это возможно. Однострочник был бы идеальным вариантом, но несколько строк тоже подойдут.

Вот что я попробовал (но не работает - исключение InvalidCastOperation):

// Sorry this is so hard to read! Also .Cast<Complex>() doesn't work either :(

return (ComplexCollection) ((List<Complex>) ((List<object>) complexElementsDictionary["ComplexElementCollection"]).OfType<Complex>()); 

Некоторые особенности этого фрагмента кода:

ComplexCollection inherits List<Complex>
complexElementsDictionary is of type (Dictionary<string, List<object>)

Таким образом, я попрошу Словарь <> для соответствующего списка объектов. Затем я пытаюсь привести этот список к тому, чем он должен быть, то есть к списку Complex.

Примечание - Пожалуйста, попробуйте игнорировать тот факт, что я кастую так во время выполнения. Я десериализирую коллекцию XML (на самом деле в app.config), и именно так я решил это сделать. Возможно, есть и лучший способ, но сейчас я просто хочу посмотреть, знает ли кто-нибудь, как сделать то, что я прошу.

Спасибо большое! Я надеюсь, что ясно, о чем я спрашиваю, и если нет, я обновлю вопрос.

Ответы [ 4 ]

3 голосов
/ 17 августа 2011

Разбиваем ваш пример кода и слегка его модифицируем, чтобы использовать Cast ():

List<object> list = complexElementsDictionary["ComplexElementCollection"];
List<Complex> typedList = list.Cast<Complex>().ToList();

Теперь у вас есть список объектов требуемого типа. Но то, что вы на самом деле хотите, это экземпляр объекта вашей коллекции, а другой объект не может его получить. То есть вы не можете сделать это:

ComplexCollection collection = (ComplexCollection)typedList;

, поскольку typedList просто не является экземпляром ComplexCollection, и компилятору не доступен оператор преобразования для преобразования из List<Complex> в ComplexCollection.

Вам нужно будет создать свой экземпляр и добавить к нему сложные объекты:

ComplexCollection collection = new ComplexCollection();
foreach(Complex c in typedList){
    collection.Add(c);
}

Или всего в четырех строках:

ComplexCollection collection = new ComplexCollection();
foreach(Complex c in complexElementsDictionary["ComplexElementCollection"].Cast<>(Complex)){
    collection.Add(c);
}
2 голосов
/ 17 августа 2011

Чтобы преобразовать List<object> в List<Complex>, достаточно просто:

List<object> objectList = complexElementsDictionary["ComplexElementCollection"];
List<Complex> complexList = objectList.Cast<Complex>().ToList();

Однако вы не можете разыграть List<Complex> в ComplexCollection только потому, что ComplexCollection наследует от List<Complex>.(наоборот, все в порядке)

List<T> имеет конструктор, который принимает IEnumerable<T> и добавляет элементы в список.Поэтому я думаю, что вам нужно добавить этот конструктор в ComplexCollection:

public ComplexCollection(IEnumerable<Complex> values) : base(values)
{
    /* plus any other logic you have */
}

И тогда ваш пример с оператором return станет:

return new ComplexCollection(
    complexElementsDictionary["ComplexElementCollection"].Cast<Complex>()
);
0 голосов
/ 17 августа 2011

Я в восторге, прямого решения нет.Может быть, вы могли бы использовать ConvertAll:

// ol is of type List<Object>
List<Complex> cl = ol.ConvertAll(o=>(Complex)c);
0 голосов
/ 17 августа 2011

Чтобы преобразовать список в новый тип, вы можете просто сделать что-то простое, как

(ComplexCollection)(yourList.Select(x => (complexType)x).ToList());

Это должно сработать, в основном вы просматриваете список объектов в словаре и приводите каждый элемент к соответствующемувведите, затем преобразуйте его в список и затем преобразуйте список в более конкретный тип коллекции.

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