protobuf-net可以序列化这种接口和泛型集合的组合吗?

发布于 2024-08-29 14:56:34 字数 1357 浏览 6 评论 0原文

我正在尝试序列化 ItemTransaction 并且 protobuf-net (r282) 有问题。

ItemTransaction : IEnumerable<KeyValuePair<Type, IItemCollection>></code>

而 ItemCollection 是这样的:

FooCollection : ItemCollection<Foo>
ItemCollection<T> : BindingList<T>, IItemCollection
IItemCollection : IList<Item>

其中 T 是 Item 的派生类型。 ItemCollection 还具有 IItemCollection 类型的属性。

我像这样进行序列化:

IItemCollection itemCol = someService.Blah(...);
...
SerializeWithLengthPrefix<IItemCollection>(stream, itemCol, PrefixStyle.Base128);

我的最终目标是序列化 ItemTransaction,但被 IItemCollection 所困扰。

Item 及其派生类型可以毫无问题地[反]序列化,请参阅[1],但反序列化 IItemCollection 会失败(序列化有效)。 ItemCollection 有一个 ItemExpression 属性,当反序列化 protobuf 时无法创建抽象类。这对我来说很有意义,但我不知道如何度过。

ItemExpression<T> : ItemExpression, IItemExpression
ItemExpression : Expression

ItemExpression 和 Expression 一样是抽象的

我如何让它正常工作?

另外,我担心 ItemTransaction 会失败,因为 IItemCollections 在编译时会有所不同且未知(ItemTransaction 将具有 FooCollection、BarCollection、FlimCollection、FlamCollection 等)。

我错过了什么(马克)?

[1] protobuf-net 跨程序集边界[反]序列化

I am trying to serialize a ItemTransaction and protobuf-net (r282) is having a problem.

ItemTransaction : IEnumerable<KeyValuePair<Type, IItemCollection>></code>

and ItemCollection is like this:

FooCollection : ItemCollection<Foo>
ItemCollection<T> : BindingList<T>, IItemCollection
IItemCollection : IList<Item>

where T is a derived type of Item. ItemCollection also has a property of type IItemCollection.

I am serializing like this:

IItemCollection itemCol = someService.Blah(...);
...
SerializeWithLengthPrefix<IItemCollection>(stream, itemCol, PrefixStyle.Base128);

My eventual goal is to serialize ItemTransaction, but am snagged with IItemCollection.

Item and it's derived types can be [de]serialized with no issues, see [1], but deserializing an IItemCollection fails (serializing works). ItemCollection has a ItemExpression property and when deserializing protobuf can't create an abstract class. This makes sense to me, but I'm not sure how to get through it.

ItemExpression<T> : ItemExpression, IItemExpression
ItemExpression : Expression

ItemExpression is abstract as is Expression

How do I get this to work properly?

Also, I am concerned that ItemTransaction will fail since the IItemCollections are going to be differing and unknown at compile time (an ItemTransaction will have FooCollection, BarCollection, FlimCollection, FlamCollection, etc).

What am I missing (Marc) ?

[1] protobuf-net [de]serializing across assembly boundaries

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

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

发布评论

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

评论(1

土豪我们做朋友吧 2024-09-05 14:56:34

我对整个情况并不完全清楚;但是 Merge 可用于传递具体项目(如果您想自己创建一个空的具体实例并让 protobuf-net 填充属性)。

如果 ItemExpression 使用 [ProtoInclude(...)] 修饰以实现预期的 ItemExpression,则它应该 允许反序列化 - 只要它从未发现需要创建抽象类型,就支持抽象类型!另请参阅我的回答显示了它的使用情况。

如果您可以提供一个我可以用来重现该问题的示例,我应该能够提供更多信息。


基于一些论坛外的例子,我想我已经得出结论,这个受支持的,但是:

  • 如果你只使用Deserialize...,最外面的IList< ;T> 导数将默认创建为 List;您可以通过使用 Merge 来解决此问题,传入您选择的具体列表实例来填充
  • 所有 ItemFoo、< code>Bar 应标记为契约类型,并在 ItemFoo 以及 Item之间使用适当的继承标记>Bar
  • 在“v2”中(很快)有更多的控制来管理具体列表类型(以及非类型化列表的项目类型),
  • 似乎确实存在与列表反序列化相关的故障,其中指定的项目类型不是根类型。这看起来已经在“v2”中自动修复了,但我需要追查它(不幸的是,这触及了包装器“WithLengthPrefix”/列出最外面的方法,我仍在研究)
  • 在“v2”中你可以这样做如果你愿意的话,整个事情不需要属性(尽管在某些时候仍然需要被告知如何)

但是是的;它应该有效。我已经通过电子邮件给您发送了一个示例,并打算整理上述最外层的方法。

I'm not entirely clear on the entire scenario; however Merge can be used to pass a concrete item in (in the case where you want to create an empty concrete instance yourself and let protobuf-net fill in the properties).

If the ItemExpression is decorated with [ProtoInclude(...)] for the expected ItemExpression<T> it should allow deserialization - abstract types are supported just as long as it never finds it needs to create one! See also my answer here which shows this in use.

If you can supply an example that I can use to reproduce the issue I should be able to provide more information.


Based on some off-forum examples, I think I've concluded that this is supported, but:

  • if you just use Deserialize..., the outmost IList<T> derivative will be created by default as List<T>; you can get around this by using Merge instead, passing in a concrete list instance of your choosing to be filled
  • all of Item, Foo, Bar should be marked as contract-types, with appropriate inheritance markers between Item and Foo, and Item and Bar
  • in "v2" (soon) there is more control to manage concrete list types (and item types for untyped lists)
  • there does seem to be a glitch related to list deserialization where the stated item type is not the root type. This looks to have been fixed automatically in "v2", but I need to chase it through (this unfortunately touches on the wrapper "WithLengthPrefix" / list outermost methods, which I'm still working on)
  • in "v2" you can do the whole thing without needing the attributes if you like (although it still needs to be told how at some point)

But yes; it should work. I've e-mailed you a sample, and intend to tidy up the aforementioned outermost methods.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文