Came across protobuf-net, awesome! I have a question regarding serialization of empty lists.
I start by declaring the object I want to serialize:
[ProtoContract]
class TestClass
{
[ProtoMember(1)]
List<int> _listOfInts = new List<int>();
public TestClass() { }
public List<int> ListOfInts
{
get { return _listOfInts; }
set { _listOfInts = value; }
}
}
If _listOfInts is empty (but not null) when I deserialse this object is will always be null. This makes sense looking at the protobuf convention and I currently work around this by adding the following method:
[ProtoAfterDeserialization]
private void OnDeserialize()
{
if (_listOfInts == null)
_listOfInts = new List<int>();
}
My question is whether I can achieve this same functionality in a more concise fashion, possibly with an additional attirbute which will initialise null/empty objects as empty instead of null?
There's a fundamental issue here in terms of how protobuf encodes data: the list itself does not appear in the data - just the elements. Because of this, there is simply nowhere obvious to store information about the list. It can be spoofed by sending a Boolean using conditional serialization, but frankly that is a bit hacky and ugly - and adds complexity. Personally, I strongly advise abstracting away from lists that could ever be null. For example:
private readonly List<Foo> items = new List<Foo>();
[ProtoMember(1)]
public List<Foo> Items { get { return items; } }
Or
private List<Foo> items;
[ProtoMember(1)]
public List<Foo> Items { get { return items ?? (items = new List<Foo>()); } }
And note that this advice isn't just about serialization: it is about avoiding arbitrary null-reference-exceptions. People don't usually expect sub-collections to be null.
If you are trying to protect against a null list you could try lazy loading in the property getter.
public List<int> ListOfInts
{
get { return _listOfInts ?? (_listOfInts = new List<int>()); }
set { _listOfInts = value; }
}
This way you can just allow the serializer to return null.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With