Как десериализовать Enumerable.ToList<>() перечислить<>
-
05-07-2019 - |
Вопрос
Я пытаюсь создать объект, который выглядит примерно так:
public class MyObject
{
private IList<AnotherObject> items;
public List<AnotherObject> Items
{
return items.AsEnumerable().ToList<AnotherObject>();
}
}
Я использую NHibernate в качестве своего DAL и сопоставляю его непосредственно с полем items, и все это работает нормально.
Я также использую рабочий процесс Windows, и действие replicator не работает с общим IList.(http://social.msdn.microsoft.com/Forums/en-US/windowsworkflowfoundation/thread/2ca74b60-fd33-4031-be4b-17a79e9afe63) Это в основном вынуждает меня использовать Список<> оболочка вместо IList<>.Это, конечно, нарушает прямое отображение NHibernate, поскольку реализация IList NHibernate не может быть приведена непосредственно к списку.
** РЕДАКТИРОВАТЬ:Требование рабочего процесса Windows на самом деле означает, что я собираюсь потерять типобезопасный доступ к списку, несмотря ни на что, поскольку для этого требуется IList.
Теперь цель состоит в том, чтобы сериализовать / десериализовать этот объект.Это прекрасно работает с двоичной сериализацией, но базовые прокси-объекты NHibernate выдают ошибки nhibernate, когда я пытаюсь их десериализовать.
Поэтому я попробовал сериализацию xml.Сериализация работает нормально и дает мне мои хорошие конкретные определения классов в сериализованном xml-файле, который полностью удаляет прокси nhibernate.Однако, пытаясь десериализовать это, я не могу добавить элементы в список в качестве элементов.AsEnumerable .Вызов ToList не позволит элементам добавляться в базовый список через .Добавить метод.
У кого-нибудь есть какие-нибудь мысли по этому поводу?Неужели я иду по этому пути неправильно?
** РЕДАКТИРОВАТЬ:Конкретный класс NHibernate - это NHibernate .Коллекция.Generic.PersistentGenericBag, который действительно реализует IList напрямую.Однако я потерял все преимущества типобезопасности универсального списка.Это возвращает меня к необходимости писать оболочку для каждого дочернего объекта, и я действительно хотел избежать этого, если это возможно.
Решение
Одним из вариантов является создание вашей собственной реализации CustomList, которая является оболочкой вокруг экземпляра, реализующего IList
т.е.:
public CustomList<AnotherObject> Items
{
return new CustomList<AnotherObject>(items);
}
т. е.когда вы добавляете к своему CustomList<T>
это дополняет список резервных копий.
Это звучит так до тех пор, пока ваш класс реализует IList
а также IList<T>
с тобой все будет в порядке.
Другие советы
Да, к сожалению, вы не можете пойти по этому пути. Вызов ToList ()
создает новый экземпляр списка, поэтому при добавлении элементов к этому экземпляру они не будут отражены в исходном списке (как вы ясно обнаружили). р>
Я не использую NHibernate, но мне было бы интересно узнать, реализует ли ваш контейнер IList
(неуниверсальная версия). Из потока, на который вы ссылались, выясняется, что System.Collections.IList
- это то, что действительно требуется (и это реализуется List < T >
, поэтому оно работает). Ваш контейнер реализует IList
?
Разве вы не можете просто разыграть это так?
public class MyObject
{
private IList<AnotherObject> items;
public List<AnotherObject> Items()
{
return (List<AnotherObject>)items;
}
}
У меня не было возможности попробовать это, но я думаю, что это должно сработать!
Я думаю, что коллекция NHibernate PersistentBag (неуниверсальная) реализует IList
, поэтому вы можете печатать элементы как IList
вместо IList < AnotherObject >
, Ссылка в вашем вопросе гласит, что проблема в том, что для репликатора требуется IList, который List < T >
реализует, а IList < T >
- нет (см. Рисунок).
Можно ли привести его к IEnumerable < T > ;? Вы можете попробовать это:
public class MyObject
{
private IList<AnotherObject> items;
public List<AnotherObject> Items
{
return new List<AnotherObject>items.Cast<AnotherObject>());
}
// or, to prevent modifying the list
public IEnumerable<AnotherObject> Items
{
return items.Cast<AnotherObject>();
}
}