我正在尝试构建一个看起来像这样的对象:
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.
发布评论
评论(5)
一个选项是创建您自己的 CustomList 实现,它是实现 IList 的实例的包装,
即:
即,当您添加到
CustomList
时,它会添加到支持列表。听起来只要您的类实现
IList
以及IList
就可以了。On option is to create your own CustomList implementation that is wrapper around an instance that implements IList
i.e:
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 asIList<T>
you will be fine.是的,不幸的是你不能这样做。 调用 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 thatSystem.Collections.IList
is what's actually required (and that's implemented byList<T>
, which is why it works). Does your container implementIList
?就不能这样投吗?
还没有机会尝试一下,但我认为它应该有效!
Can't you just cast it like this?
Havent had the chanse to try it out, but I think it should work!
我认为 NHibernate PercientBag(非通用)集合实现了
IList
,因此您可以将项目键入为IList
而不是IList
。 您问题中的链接表明问题在于复制器需要一个List
实现的 IList,但IList
没有(见图)。I think the NHibernate PersistentBag (non-generic) collection implements
IList
so you could type items asIList
instead ofIList<AnotherObject>
. The link in your question states that the problem is that replicator requires an IList whichList<T>
implements butIList<T>
does not (go figure).可以转换为 IEnumerable 吗? 你可以试试这个:
Can it be cast to IEnumerable<T>? You could try this: