I am recently trying to use protobuf.net for serializing objects for network communication in a .net application. Protobuf is a great format for sending data. Protobuf tries to be very frugal to save bandwidth. However, this causes some unexpected side effects when using it with .NET.
For example, If there is a collection serialized and the collection count was zero, then the serializer is going to write out null and this collection will be deserialized as null on the other end.
This is easy to fix when you have only a few classes that holding your models, but it can be a huge problem when you have a very large number of classes that you are trying to serialize and the previously used serializer was always deserializing an empty collection to an empty collection.
To solve this, we need extra wrapper class and within this wrapper class, it is possible to detect if the underlying generic type is an IEnumerable<T> and create code to initialize the data member as an empty collection if needed.
The code below demonstrates how to use this technique.
public class DataWrapper<T>
{
public T Data { get; set; }
public DataWrapper()
{
Type dataType = typeof(T);
// Protobuf deserializes empty collections as null in order to combat this we create an empty collection by default
if (dataType.IsGenericType && dataType.GetGenericTypeDefinition() == typeof(IEnumerable<>))
{
Type underlyingType = entityType.GetGenericArguments()[0];
var listType = typeof(List<>);
var concreteType = listType.MakeGenericType(underlyingType);
Data = (TEntity)Activator.CreateInstance(concreteType);
}
else
{
Data = default(T);
}
}
}