The wire format (defined by google – not inside my control!) only sends data for items. It makes no distinction between an empty list and a null list. So if there is no data to send – yes, the length is 0 (it is a very frugal format ;-p).
Protocol buffers do not include any type metadata on the wire.
Another common gotcha here is that you might assume your list property is automatically instantiated as empty, but it won’t be (unless your code does it, perhaps in a field initializer or constructor).
Here’s a workable hack:
[ProtoContract]
class SomeType {
[ProtoMember(1)]
public List<SomeOtherType> Items {get;set;}
[DefaultValue(false), ProtoMember(2)]
private bool IsEmptyList {
get { return Items != null && Items.Count == 0; }
set { if(value) {Items = new List<SomeOtherType>();}}
}
}
Hacky maybe, but it should work. You could also lose the Items “set” if you want and just drop the bool:
[ProtoMember(1)]
public List<SomeOtherType> Items {get {return items;}}
private readonly List<SomeOtherType> items = new List<SomeOtherType>();
[DefaultValue(false), ProtoMember(2)]
private bool IsEmptyList {
get { return items.Count == 0; }
set { }
}