简体   繁体   English

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

[英]How to deserialize Enumerable.ToList<>() to List<>

I'm trying to build an object that looks something like this: 我正在尝试构建一个看起来像这样的对象:

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

I'm using NHibernate as my DAL and have it mapping directly to the items field and all that works fine. 我正在使用NHibernate作为我的DAL并将其直接映射到items字段,所有这些都可以正常工作。

I'm also using Windows Workflow and the replicator activity doesn't work with the generic IList. 我也使用Windows Workflow,复制器活动不适用于通用IList。 ( http://social.msdn.microsoft.com/Forums/en-US/windowsworkflowfoundation/thread/2ca74b60-fd33-4031-be4b-17a79e9afe63 ) This is basically forcing me to use the List<> wrapper instead of the IList<>. http://social.msdn.microsoft.com/Forums/en-US/windowsworkflowfoundation/thread/2ca74b60-fd33-4031-be4b-17a79e9afe63 )这基本上迫使我使用List <>包装而不是IList < >。 This of course breaks the direct NHibernate mapping as NHibernate's IList implementation can't be cast directly to a List. 这当然打破了直接的NHibernate映射,因为NHibernate的IList实现不能直接转换为List。

** EDIT: The Windows Workflow requirement actually means I'm going to lose type-safe access to the list no matter what as it requires an IList. **编辑:Windows Workflow要求实际上意味着我将失去对列表的类型安全访问,无论它需要IList。

Now the goal is to serialize/deserialize this object. 现在的目标是序列化/反序列化此对象。 This works fine with binary serialization but the underlying NHibernate proxy objects explode with nhibernate errors when I try to deserialize them. 这适用于二进制序列化,但当我尝试反序列化时,底层的NHibernate代理对象会出现nhibernate错误。

So I tried xml serialization. 所以我尝试了xml序列化。 The serialization works fine and gives me my nice concrete class definitions in the serialized xml file which strips out the nhibernate proxies completely. 序列化工作正常,并在序列化的xml文件中给出了我很好的具体类定义,它完全剥离了nhibernate代理。 However, when attempting to deserialize this, I'm unable to add the items to the list as the items.AsEnumerable.ToList call won't let items get added to the underlying list via the .Add method. 但是,当尝试反序列化时,我无法将项目添加到列表中作为items.AsEnumerable.ToList调用将不允许项目通过.Add方法添加到基础列表。

Does anyone have any thoughts on this? 有没有人对此有任何想法? Am I going about this the wrong way? 我是以错误的方式来做这件事的吗?

** EDIT: The NHibernate concrete class is NHibernate.Collection.Generic.PersistentGenericBag which does indeed implement IList directly. **编辑:NHibernate具体类是NHibernate.Collection.Generic.PersistentGenericBag确实直接实现IList。 However, I lost all the type-safe benefits of the generic list. 但是,我失去了通用列表的所有类型安全的好处。 This puts me back in the realm of having to write a wrapper for each child object and I really wanted to avoid that if possible. 这让我回到必须为每个子对象编写包装器的领域,如果可能的话我真的想避免这种情况。

On option is to create your own CustomList implementation that is wrapper around an instance that implements IList 选项是创建自己的CustomList实现,该实现是实现IList的实例的包装

ie: 即:

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

ie when you add to your CustomList<T> it adds to the backing list. 即,当您添加到CustomList<T>它会添加到支持列表中。

It sounds like so long as your class implements IList as well as IList<T> you will be fine. 听起来只要你的类实现IList以及IList<T>就可以了。

Yes, unfortunately you can't go about it this way. 是的,不幸的是你不能这样做。 Calling ToList() creates a brand new instance of the list, so when you add items to that instance they aren't going to be reflected in the original list (as you've clearly discovered). 调用ToList()会创建列表的全新实例,因此当您向该实例添加项目时,它们不会反映在原始列表中(正如您已经清楚地发现的那样)。

I don't use NHibernate, but I would be curious to see if your container implements IList (the non-generic version). 我不使用NHibernate,但我很想知道你的容器是否实现了IList (非泛型版本)。 From the thread you referenced, it appears that System.Collections.IList is what's actually required (and that's implemented by List<T> , which is why it works). 从您引用的线程看来, System.Collections.IList似乎是实际需要的(并且由List<T> ,这就是它工作的原因)。 Does your container implement IList ? 你的容器是否实现了IList

Can't you just cast it like this? 你不能像这样投这个吗?

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

Havent had the chanse to try it out, but I think it should work! 没有试图尝试它,但我认为它应该工作!

I think the NHibernate PersistentBag (non-generic) collection implements IList so you could type items as IList instead of IList<AnotherObject> . 我认为NHibernate PersistentBag(非泛型)集合实现了IList因此您可以将项目类型化为IList而不是IList<AnotherObject> The link in your question states that the problem is that replicator requires an IList which List<T> implements but IList<T> does not (go figure). 您的问题中的链接指出问题是复制器需要一个IList,其中List<T>实现但IList<T>没有(如图)。

Can it be cast to IEnumerable<T>? 可以转换为IEnumerable <T>吗? You could try this: 你可以试试这个:

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 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM