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

发布于 2024-07-19 03:45:08 字数 1281 浏览 3 评论 0 原文

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

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

我使用 NHibernate 作为我的 DAL 并将其直接映射到 items 字段,并且一切正常。

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

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

现在的目标是序列化/反序列化该对象。 这对于二进制序列化工作得很好,但是当我尝试反序列化它们时,底层 NHibernate 代理对象会出现 nhibernate 错误。

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

有人对此有什么想法吗? 我是否以错误的方式处理这个问题?

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

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.

I'm also using Windows Workflow and the replicator activity doesn't work with the generic 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<>. This of course breaks the direct NHibernate mapping as NHibernate's IList implementation can't be cast directly to a 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.

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.

So I tried xml serialization. The serialization works fine and gives me my nice concrete class definitions in the serialized xml file which strips out the nhibernate proxies completely. 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.

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. 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

凉世弥音 2024-07-26 03:45:08

一个选项是创建您自己的 CustomList 实现,它是实现 IList 的实例的包装,

即:

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

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

听起来只要您的类实现 IList 以及 IList 就可以了。

On option is to create your own CustomList implementation that is wrapper around an instance that implements IList

i.e:

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

i.e. when you add to your CustomList<T> it adds to the backing list.

It sounds like so long as your class implements IList as well as IList<T> you will be fine.

余生再见 2024-07-26 03:45:08

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

我不使用 NHibernate,但我很好奇您的容器是否实现了 IList(非通用版本)。 从您引用的线程来看,似乎 System.Collections.IList 是实际需要的(并且由 List 实现,这就是它起作用的原因)。 您的容器是否实现了IList

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).

I don't use NHibernate, but I would be curious to see if your container implements IList (the non-generic version). 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). Does your container implement IList?

猥琐帝 2024-07-26 03:45:08

就不能这样投吗?

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

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

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!

我还不会笑 2024-07-26 03:45:08

我认为 NHibernate PercientBag(非通用)集合实现了 IList,因此您可以将项目键入为 IList 而不是 IList。 您问题中的链接表明问题在于复制器需要一个 List 实现的 IList,但 IList 没有(见图)。

I think the NHibernate PersistentBag (non-generic) collection implements IList so you could type items as IList instead of 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).

风蛊 2024-07-26 03:45:08

可以转换为 IEnumerable 吗? 你可以试试这个:

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

Can it be cast to 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>();
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文