问题
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.IEnumerable
1[MyType]`. Second I think I will be unable to desirialize it based on manual, and protobuf-net source code analyzes.
- Is there a way to extend protobuf-net to supply delegate to external Add method in ProtoMemeber attribute?
- Why using
ProtoMember(1, OverwriteList=true)
doesn't work? Doesn't it suppose to overwrite collection and shouldn't care aboutAdd<T>()
method? Why it just don't try to set this property to T[] orList<T>
or any set assignable toIEnumerable<T>
? - 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 - What options I have except creating inherited
MyTypeCollection<T> : Collection<T>
?
回答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 anAdd
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 implementedIEnumerable<T>
(returning_itemsSet.GetEnumerator()
etc), then it would find theAdd
automaticallyI 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 aList<T>
here)It isn't something I've investigated, to be honest; so: no
The type exposed in the property must, as a minimum: implement
IEnumerable
(althoughIEnumerable<T>
would be preferred), and expose anAdd(T)
method. It doesn't have to beCollection<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.
回答2:
I was trying to cut corners, and to reuse my model as a message contract, but this is actually wrong aproach. The way to go is to create DTO's specialized classes and converter to you model, anyway it's good to separate your model from messages.
I must criticize Marc though, for adding ProtoContract and ProtoMemeber attributes that lure users to reuse their model by attributing it.
来源:https://stackoverflow.com/questions/7793527/protobuf-net-serializing-ienumerablet