如何在Protobuf-Net中保留一个可以为空的值的数组?

我正在从BinaryFormatter迁移到Protobuf-net(到目前为止,它似乎在存储大小和反序列化时间方面提供了巨大的改进)。

然而,我遇到的一个问题是double?[]数组不会以序列化的相同forms反序列化。 数组中任何null的值都会被全部删除 – 即如果我从一个包含6个元素[null,null,1,2,3,null]的数组开始,在反序列化后我最终得到一个数组[1 ,2,3]。 对于我的程序,我必须以与序列化之前完全相同的forms检索这些数组 – 如果使用BinaryFormatter则会发生这种情况。

到目前为止我提出的一个解决方案是为每一个创建两个数组,一个是double [],其中每个元素都有一个值,另一个是bool [],它可以用来描述原始值是否为null – 但是由于各种原因,这是非常低效的。

我可以在之前的相关问题中看到,ProtoMember可能有一个’SupportNull’选项,但是我找不到任何文档清楚地显示如何实现它,并且无法通过游戏来解决这个问题。

任何人都可以提供的帮助将非常感激。

using ProtoBuf; using ProtoBuf.Meta; using System; [ProtoContract] class Foo { [ProtoMember(1)] public double?[] Values { get; set; } } static class Program { static void Main() { // configure the model; SupportNull is not currently available // on the attributes, so need to tweak the model a little RuntimeTypeModel.Default.Add(typeof(Foo), true)[1].SupportNull = true; // invent some data, then clone it (serialize+deserialize) var obj = new Foo { Values = new double?[] {1,null, 2.5, null, 3}}; var clone = Serializer.DeepClone(obj); // check we got all the values back foreach (var value in clone.Values) { Console.WriteLine(value); } } } 

它实际上不支持开箱即用,你必须操纵RuntimeTypeModel来显式设置它应该允许空值。

RuntimeTypeModel.Default[typeof(YourObjectType)][(tag)].SupportNull = true;

例:

 var nullable = new ObjectWithNullables() { IntArray = new int?[] { null, 1, 2, null } }; // returns 2 elements out of 4 //var resultA = Deserialize(Serialize(nullable)); RuntimeTypeModel.Default[typeof(ObjectWithNullables)][1].SupportNull = true; // returns 4 elements out of 4 var resultA = Deserialize(Serialize(nullable)); [ProtoContract] public class ObjectWithNullables { [ProtoMember(1)] public int?[] IntArray { get; set; } }