2009-05-05 87 views
5

我试图建立一个对象,它看起来是这样的:如何反序列化Enumerable.ToList <>()为List <>

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

我使用NHibernate作为我DAL和有它映射直接到项目字段和所有工作正常。

我也使用Windows工作流和复制器活动不能与通用IList一起使用。 (http://social.msdn.microsoft.com/Forums/en-US/windowsworkflowfoundation/thread/2ca74b60-fd33-4031-be4b-17a79e9afe63)这基本上迫使我使用列表<>包装,而不是IList <>。这当然会破坏直接的NHibernate映射,因为NHibernate的IList实现不能直接转换为List。

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

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

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

有没有人对此有任何想法?我是否以这种错误的方式去做?

**编辑:NHibernate具体类是NHibernate.Collection.Generic.PersistentGenericBag确实实现IList直接。但是,我失去了通用列表的所有类型安全的好处。这使我不得不为每个子对象编写一个包装器,我真的想尽可能避免这种情况。

回答

2

在选择是创建你自己的CustomList实现,它是围绕着实现IList

即一个实例包装:

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

即当您添加到您的CustomList<T>其添加到后台列表。

这听起来像只要你的班级实施IList以及IList<T>你会没事的。

+0

我正在考虑包装路线,但我并不想为我的领域模型中的每个子对象编写包装。那么泛型又有什么意义呢? :)我承认这可能是最后的解决方案。 – 2009-05-05 18:58:26

1

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

我不使用NHibernate,但我会好奇你的容器是否实现了IList(非通用版本)。从您引用的主题看,System.Collections.IList是实际需要的(并且由List<T>实现,这就是它工作的原因)。你的容器是否实施IList

+1

我不得不为了适应NHibernate的使用IList的但Windows工作流要求列表。 – 2009-05-05 18:40:53

+0

NHibernate.Collection.Generic.PersistentGenericBag 确实实现了IList。我可以使用它,但是我失去了我不想做的通用列表的类型安全性。另一种方法是按照Alex的建议编写一个封装器,但这不是我的理想解决方案。 – 2009-05-05 19:00:12

+1

无论你做什么,你都会失去型号安全。这就是为什么List 没有实施IList;它要求你打开一个接口,它将在语法上允许你添加一个实际上不匹配泛型类型的元素。你会在序列化的“另一面”访问这个IList吗?如果是这样的话,你将无法将它投回IList 吗? – 2009-05-05 19:03:29

0

难道你不能像这样施放它吗?

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

没有尝试过,但我认为它应该工作!

0

我觉得NHibernate的PersistentBag(非泛型)集合实现了IList,所以你可以输入项目为IList而不是IList<AnotherObject>。你的问题中的链接指出,问题是复制器需要一个IList,其中List<T>实现,但IList<T>不(请参阅图)。

0

它可以投射到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>(); 
    } 
} 
相关问题