Вопрос

Я пытаюсь создать объект, который выглядит примерно так:

  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>();
    }
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top