Differentiation between empty lists and null lists cannot be worked around using Surrogates in protobuf-net [closed]
protobuf does not have built-in support of differentation between empty lists and null lists. However, our business objects do differ because null means that the list has not been pulled from the database yet whereas empty means no items found.
So I am trying to overcome this limitation using Surrogates in protobuf-net. The problem, however, is, that my surrogate does not get called at all.
Here is what I am doing:
//DataContracts
[ProtoContract]
public class SerializeClassCollectionContainer
{
[ProtoMember(1, AsReference=true)]
public SerializeClassCollection Collection { get; set; }
}
[ProtoContract]
public class SerializeClassCollection : List<SerializeClass>
{
}
[ProtoContract]
public class SerializeClassCollectionSurrogate
{
[ProtoMember(1)]
public bool IsEmpty { get; set; }
[ProtoMember(2, AsReference = true)]
public List<SerializeClass> Elements { get; set; }
public static implicit operator SerializeClassCollection(SerializeClassCollectionSurrogate surrogate)
{
if (surrogate == null)
return null;
if (surrogate.Elements != null)
{
var col = new SerializeClassCollection();
col.AddRange(surrogate.Elements);
return col;
}
if (surrogate.IsEmpty)
{
return new SerializeClassCollection();
}
return null;
}
public static implicit operator SerializeClassCollectionSurrogate(SerializeClassCollection collection)
{
if (collection == null)
return null;
var surrogate = new SerializeClassCollectionSurrogate();
surrogate.IsEmpty = collection.Count == 0;
surrogate.Elements = collection.ToList();
return surrogate;
}
}
//Evaluation
RuntimeTypeModel.Default[typeof(SerializeClassCollection)].SetSurrogate(typeof(Surrogates.SerializeClassCollectionSurrogate));
SerializeClassCollectionContainer serializeClassCollectionContainer = GetCustomObject();
serializeClassCollectionContainer.Collection = new SerializeClassCollection(); //empty collection
using (var writer = new StreamWriter(OutputDir + "proto.bin"))
{
Serializer.Serialize(writer.BaseStream, serializeClassCollectionContainer);
}
using(var reader = new StreamReader(OutputDir + "proto.bin"))
{
var deserialized = Serializer.Deserialize<SerializeClassCollectionContainer>(reader.BaseStream);
if(deserialized.Collection == null)
throw new InvalidOperationException("Surrogate does not work");
}
Am I doing something wrong? Or is this a feature and not supposed to work? Or is it supposed to work but a bug?
I tried this with revision 433 from the protobuf-net trunk.
Regards, TH
精彩评论