Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ProtoBuf-net serializing IEnumerable<T>

I'm trying to use ProtoBuf-NET in my project (it's mostly Silverlight 4 project).

I'm having difficulties serializing my Model collections, they all are defined like this:

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

Update: First I can't serialize it - No serializer defined for type: System.Collections.Generic.IEnumerable1[MyType]`. Second I think I will be unable to desirialize it based on manual, and protobuf-net source code analyzes.

  1. Is there a way to extend protobuf-net to supply delegate to external Add method in ProtoMemeber attribute?
  2. Why using ProtoMember(1, OverwriteList=true) doesn't work? Doesn't it suppose to overwrite collection and shouldn't care about Add<T>() method? Why it just don't try to set this property to T[] or List<T> or any set assignable to IEnumerable<T> ?
  3. Is there a way to supply custom reflection mechanism to work with private fields in Silverlight, like: implementing: public interface IReflectable{ object GetValue(FieldInfo field); void SetValue(FieldInfo field, object value); } to work with private fields. I have used such approach to work with private fields with Db4o: http://community.versant.com/Forums/tabid/98/aft/10881/Default.aspx
  4. What options I have except creating inherited MyTypeCollection<T> : Collection<T> ?
like image 256
Alex Burtsev Avatar asked Oct 17 '11 12:10

Alex Burtsev


1 Answers

  1. not at current, no; the type exposed must have (at a minimum) an Add method. While I have no objection to investigating the possibility of an Add outside the object itself, this is complicated since you are then looking at a different "primary" object (the sequence vs the container). However; if your parent object implemented IEnumerable<T> (returning _itemsSet.GetEnumerator() etc), then it would find the Add automatically

  2. I can't see the context here; however, I suspect that without the Add it still isn't happy to consider it a list in the first place. I see the way you are going with that, though, and it is perhaps a way it could reason "I can use a List<T> here)

  3. It isn't something I've investigated, to be honest; so: no

  4. The type exposed in the property must, as a minimum: implement IEnumerable (although IEnumerable<T> would be preferred), and expose an Add(T) method. It doesn't have to be Collection<T> / List<T> / etc - simply: it must (at present) have some mechanism to add. IList<T> would be a a pragmatic option, but I gather that isn't quite what you want.

Jonathan is right that a surrogate for the outer-class (the thing which has _itemsSet, TSet and AddT) might also be an option.

If the outer-class only exists to have the collection and the add method, then just adding : IEnumerable<T> and renaming AddT to Add would probably make it work.

like image 92
Marc Gravell Avatar answered Sep 26 '22 07:09

Marc Gravell