ProtoBuf-net序列化IEnumerable <t> </t>

时间:2011-10-17 12:10:39

标签: c# silverlight protobuf-net

我正在尝试在我的项目中使用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源代码分析来完成它。

  1. 有没有办法在protoMemeber属性中扩展protobuf-net以将代理提供给外部的Add方法?
  2. 为什么使用ProtoMember(1, OverwriteList=true)不起作用?它不是要覆盖集合而不应该关心Add<T>()方法吗?为什么它只是不尝试将此属性设置为T []或List<T>或任何可分配给IEnumerable<T>的设置?
  3. 有没有办法提供自定义反射机制来处理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
  4. 除了创建继承的MyTypeCollection<T> : Collection<T>之外,我有哪些选项?

2 个答案:

答案 0 :(得分:4)

  1. 不是现在,不是;暴露的类型必须(至少)Add方法。虽然我不反对调查在对象本身之外Add的可能性,但这很复杂,因为您正在查看不同的“主要”对象(序列与容器) 。然而;如果对象已实施IEnumerable<T>(返回_itemsSet.GetEnumerator()等),则会自动找到Add

  2. 我在这里看不到上下文;但是,我怀疑如果没有Add,它仍然不乐意将它作为一个列表首先考虑。不过,我看到了你的方式,也许这可能是“我可以在这里使用List<T>”的理由

  3. 说实话,这不是我调查过的事情;所以:没有

  4. 属性中公开的类型必须至少:实现IEnumerable(尽管IEnumerable<T>是首选),并公开Add(T)方法。它不必是Collection<T> / List<T> / etc - 简单地说:它必须(目前)有一些机制来添加。 IList<T>将是一个务实的选择,但我认为这不是你想要的。

  5. Jonathan对于外部类的替代是正确的( _itemsSetTSetAddT )也可能是一种选择。

    如果仅存在外部类 以拥有集合和add方法,那么只需添加: IEnumerable<T>并将AddT重命名为Add即可它有效。

答案 1 :(得分:1)

我试图偷工减料,并将我的模型作为消息合同重用,但这实际上是错误的方法。要做的就是为你的模型创建DTO的专用类和转换器,无论如何最好将模型与消息分开。

我必须批评Marc,因为它添加了ProtoContract和ProtoMemeber属性,引诱用户通过归因来重用他们的模型。