ProtoBuf-net 序列化 IEnumerable<T>
Posted
技术标签:
【中文标题】ProtoBuf-net 序列化 IEnumerable<T>【英文标题】:ProtoBuf-net serializing IEnumerable<T> 【发布时间】:2011-10-17 12:10:39 【问题描述】:我正在尝试在我的项目中使用 ProtoBuf-NET(主要是 Silverlight 4 项目)。
我在序列化我的模型集合时遇到了困难,它们都是这样定义的:
private List<T> _itemsSet;
public IEnumerable<T> TSet
get return _itemsSet;
set _itemsSet = value == null ? new List<T>() : new List<T>(value);
public void AddT(T item)
//Do my logic here
_itemsSet.Add(item);
更新:首先我无法序列化它 - No serializer defined for type: System.Collections.Generic.IEnumerable
1[MyType]`。其次,我认为我将无法根据手动和 protobuf-net 源代码分析对其进行反序列化。
-
有没有办法扩展 protobuf-net 以向 ProtoMemeber 属性中的外部 Add 方法提供委托?
为什么使用
ProtoMember(1, OverwriteList=true)
不起作用?它不应该覆盖集合并且不应该关心Add<T>()
方法吗?为什么不尝试将此属性设置为 T[] 或 List<T>
或任何可分配给 IEnumerable<T>
的集合?
有没有办法提供自定义反射机制来处理 Silverlight 中的私有字段,例如:实现:public interface IReflectable object GetValue(FieldInfo field); void SetValue(FieldInfo field, object value);
来处理私有字段。我已经使用这种方法来处理带有 Db4o 的私有字段:http://community.versant.com/Forums/tabid/98/aft/10881/Default.aspx
除了创建继承的MyTypeCollection<T> : Collection<T>
,我还有哪些选择?
【问题讨论】:
您是否尝试过在包含类上实现ISerializable
?
我已将其归因于 ProtoContract(IEnumerable 通用参数类型)
您可能还会发现Surrogates 很有用。
【参考方案1】:
目前没有,没有;暴露的类型必须具有(至少)Add
方法。虽然我不反对调查对象本身之外的Add
的可能性,但这很复杂,因为您正在查看不同的“主要”对象(序列与容器)。然而;如果你的 parent 对象实现了IEnumerable<T>
(返回_itemsSet.GetEnumerator()
等),那么它会自动找到Add
我看不到这里的上下文;但是,我怀疑如果没有Add
,它仍然不乐意将其视为列表首先。不过,我看到了你的做法,这也许是它可以推理“我可以在这里使用List<T>
”的一种方式
说实话,这不是我调查过的事情。所以:没有
属性中公开的类型至少必须:实现IEnumerable
(尽管首选IEnumerable<T>
),并公开Add(T)
方法。它不必是 Collection<T>
/ List<T>
/ 等等 - 简单地说:它必须(目前)有 some 机制来添加。 IList<T>
是一个务实的选择,但我认为这不是你想要的。
乔纳森是对的,外部阶级的替代品(拥有_itemsSet
、TSet
和AddT
)也可能是一种选择.
如果存在 only 的外部类具有集合和 add 方法,那么只需添加 : IEnumerable<T>
并将 AddT
重命名为 Add
可能会使其工作。
【讨论】:
我的 IEnumerableT 序列化问题怎么办?我已经使用最新的 protobuf-net 源代码在调试模式下运行我的代码,并且没有 Collection | IEnumerableIEnumerable<T>
不可序列化,因为它不能稳健地反序列化它。充其量,我可以给你一个更好的错误信息!它可以(我真的非常希望)处理“Collection”——但它需要有一些 API在暴露的类型上到Add
的东西。
你打算继续在 protobuf-net 上工作并扩展它吗?什么是项目状态?我希望在现实生活项目中使用它,但在目前的状态下,它对我来说无法使用,认为它仍然比从头开始编写自己的解决方案要好。
@Alex 它正在积极开发和使用中。重新扩展它 - 首先我需要清楚地理解这个问题,一个更完整的例子将有很大帮助。
@G-Mac 我不能指责你的论点;我可以支持这种情况 - 它将在下一次部署中工作【参考方案2】:
我试图偷工减料,将我的模型重用为消息合约,但这实际上是错误的做法。可行的方法是为您的模型创建 DTO 的专用类和转换器,无论如何最好将您的模型与消息分开。
不过,我必须批评 Marc,因为他添加了 ProtoContract 和 ProtoMemeber 属性,通过归因来诱使用户重复使用他们的模型。
【讨论】:
批评可能是件好事,但我很好奇你会让我做什么(在这里也要考虑 XmlSerializer 的属性、DataContractSerializer 的属性等)。碰巧的是,在 v2 中,如果您愿意,一切 都可以在没有属性的情况下完成。如果我能看到一个足以运行的完整场景,我会很乐意提供更多输入(目前,我只有一个类的片段,这不容易理解上下文并提供输入)以上是关于ProtoBuf-net 序列化 IEnumerable<T>的主要内容,如果未能解决你的问题,请参考以下文章