如何将Ienumerable.ToList<>()反序列化为List<>

时间:2009-05-05 18:31:11

标签: c# nhibernate xml-serialization workflow-foundation

我正在尝试构建一个看起来像这样的对象:

  public class MyObject
  {
    private IList<AnotherObject> items;
    public List<AnotherObject> Items
    {
      return items.AsEnumerable().ToList<AnotherObject>();
    }
  }

我正在使用NHibernate作为我的DAL并将其直接映射到items字段,所有这些都可以正常工作。

我也使用Windows Workflow,复制器活动不适用于通用IList。 (http://social.msdn.microsoft.com/Forums/en-US/windowsworkflowfoundation/thread/2ca74b60-fd33-4031-be4b-17a79e9afe63)这基本上迫使我使用List&lt;&gt;包装器而不是IList&lt;&gt;。这当然打破了直接NHibernate映射,因为NHibernate的IList实现不能直接转换为List。

**编辑:Windows Workflow要求实际上意味着我将失去对列表的类型安全访问,无论它需要IList。

现在的目标是序列化/反序列化此对象。这适用于二进制序列化,但当我尝试反序列化时,底层NHibernate代理对象会出现nhibernate错误。

所以我尝试了xml序列化。序列化工作正常,并在序列化的xml文件中给出了我很好的具体类定义,它完全剥离了nhibernate代理。但是,在尝试反序列化时,我无法将项目添加到列表中作为items.AsEnumerable.ToList调用将不允许通过.Add方法将项目添加到基础列表。

有没有人对此有任何想法?我是以错误的方式来做这件事的吗?

**编辑:NHibernate具体类是NHibernate.Collection.Generic.PersistentGenericBag,它确实直接实现了IList。但是,我失去了通用列表的所有类型安全的好处。这让我回到必须为每个子对象编写包装器的领域,如果可能的话我真的想避免这种情况。

5 个答案:

答案 0 :(得分:2)

On选项是创建自己的CustomList实现,该实现是实现IList

的实例的包装

即:

public CustomList<AnotherObject> Items    
{      
    return new CustomList<AnotherObject>(items); 
}

即。当您添加到CustomList<T>时,它会添加到支持列表中。

只要您的班级实施IList以及IList<T>,您就可以了。

答案 1 :(得分:1)

是的,不幸的是你不能这样做。调用ToList()会创建一个全新的列表实例,因此当您向该实例添加项目时,它们不会反映在原始列表中(正如您已经清楚地发现的那样)。

我不使用NHibernate,但我很想知道你的容器是否实现IList(非通用版本)。从您引用的主题看来,System.Collections.IList似乎是实际需要的(并且由List<T>实现,这就是它的工作原理)。您的容器是否实现了IList

答案 2 :(得分:0)

难道你不能像这样投这个吗?

public class MyObject
{
    private IList<AnotherObject> items;
    public List<AnotherObject> Items()
    {
        return (List<AnotherObject>)items;
    }
}

没有机会尝试,但我认为它应该有效!

答案 3 :(得分:0)

我认为NHibernate PersistentBag(非泛型)集合实现了IList,因此您可以将项目键入IList而不是IList<AnotherObject>。您的问题中的链接指出问题是复制器需要IList List<T>实现但IList<T>没有(如图)。

答案 4 :(得分:0)

可以转换为IEnumerable&lt; T&gt;?你可以试试这个:

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