使用Protobuf-net序列化可空双精度浮点数列表时出现问题

4

我已经可以序列化可空的 double 类型,也可以序列化其他类型的可空列表,但无法序列化可空 double 类型的列表。

如果我这样做:

        List<double?> aList = new List<double?>();
        aList.Add(0.1);
        aList.Add(null);
        Serializer.Serialize(ms, aList);

我遇到了这个错误:
System.NullReferenceException: 对象引用未设置为对象的实例。 在 c:\Dev\protobuf-net\protobuf-net\Meta\TypeModel.cs 的第 169 行 ProtoBuf.Meta.TypeModel.TrySerializeAuxiliaryType(ProtoWriter writer, Type type, DataFormat format, Int32 tag, Object value, Boolean isInsideList) 在 c:\Dev\protobuf-net\protobuf-net\Meta\TypeModel.cs 的第 188 行 ProtoBuf.Meta.TypeModel.SerializeCore(ProtoWriter writer, Object value) 在 c:\Dev\protobuf-net\protobuf-net\Meta\TypeModel.cs 的第 217 行 ProtoBuf.Meta.TypeModel.Serialize(Stream dest, Object value, SerializationContext context) 在 c:\Dev\protobuf-net\protobuf-net\Meta\TypeModel.cs 的第 201 行 ProtoBuf.Meta.TypeModel.Serialize(Stream dest, Object value) 在 c:\Dev\protobuf-net\protobuf-net\Serializer.cs 的第 87 行 ProtoBuf.Serializer.Serialize[T](Stream destination, T instance)
这个代码应该可以工作吗?我做错了什么吗?

我使用了一个 List<int?>、一个 List<double?> 和一个 List<string> 来进行测试,它们在这里的表现都是相同的。 - Marc Gravell
我将重新运行我的测试并返回。 - mcmillab
我使用所有可空类型时都遇到了相同的行为。我认为以前虽然我有可空类型,但只有可空的 double 类型具有实际的 null 值。对于错误信息,我很抱歉。Ben - mcmillab
1个回答

3

这里的主要问题是,protobuf规范根本没有空值的概念-无法在protobuf格式中明确表达空值/缺失值。

在每个库的基础上,该库本身可以选择欺骗一种额外的层以允许这种情况,但是:

  • 它会占用额外的字节
  • 它会使代码复杂化并需要额外的配置
  • 它会(必然)禁用像“紧凑编码”之类的优化

虽然这样做有点小题大做,但应该能检测到空值并更好地处理!

我建议您序列化一个具有可空值的事物列表,而不是序列化一个具有可空值的列表本身。例如:

[ProtoContract]
public class Foo {
    [ProtoMember(1)] public double? Value {get;set;}
}

一个以上的列表可以表示空值。基本上,这与如果我添加了内置支持来欺骗nulls所写的内容完全相同。

对我来说,它适用于其他可空类型却不适用于双精度浮点数确实有些奇怪。尽管如此,你的解释是有道理的,我会采纳建议的解决方案,谢谢。 - mcmillab
@mcmillab 等等……它在其他可空类型中也起作用了吗?我会调查一下,以确保没有发生什么愚蠢的事情。我上面说的仍然是正确的(格式限制等等)- 但我会看看双精度浮点数是否有什么奇怪的地方。 - Marc Gravell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接