protobuf-net 保留未来字段

Posted

技术标签:

【中文标题】protobuf-net 保留未来字段【英文标题】:protobuf-net keeping future fields 【发布时间】:2014-01-24 11:39:33 【问题描述】:

我现在对此进行了一些谷歌搜索,但无法确定 protobuf-net 或 protobuf 通常是否支持以下意义上的前向兼容性:

对象的旧版本使用新字段反序列化对象的新版本,但在将其序列化回来时会保留此字段,因此新版本的对象不会丢失值。

protobuf 可以做到这一点吗?

非常感谢

【问题讨论】:

【参考方案1】:

是的;大多数 protobuf 实现都支持往返未知数据。由于您特别标记了 protobuf-net - 如果您使用代码优先(即手动编写类,这在 protobuf-net 中很常见),那么您需要明确地为此提供支持。最简单的方法是继承Extensible。下面显示了通过一个对该字段一无所知的类型成功的往返:

using System;
using System.IO;
using ProtoBuf;

[ProtoContract]
class Foo

    [ProtoMember(1)]
    public int X  get;set; 
    [ProtoMember(2)]
    public int Y  get;set; 

[ProtoContract]
class Bar : Extensible

    [ProtoMember(1)]
    public int A  get;set;  // if declared, needs to be compatible

    // note we don't have a declared field 2 here

static class Program

    static void Main()
    
        Foo orig = new Foo  X = 123, Y = 456 , clone;
        Bar bar;
        using(var ms = new MemoryStream())
        
            Serializer.Serialize(ms, orig);
            ms.Position = 0;
            bar = Serializer.Deserialize<Bar>(ms);

            Console.WriteLine(bar.A); // 123 // query known data
            int b = Extensible.GetValue<int>(bar, 2); // query unknown data
            Console.WriteLine(b); // 456
        
        using (var ms = new MemoryStream())
        
            Serializer.Serialize(ms, bar);
            ms.Position = 0;
            clone = Serializer.Deserialize<Foo>(ms);
        
        Console.WriteLine(clone.X); // 123
        Console.WriteLine(clone.Y); // 456
    

【讨论】:

非常感谢马克!港口做得很好。享受使用它!

以上是关于protobuf-net 保留未来字段的主要内容,如果未能解决你的问题,请参考以下文章

使用protobuf-net继承时如何选择字段号?

Protobuf-net / NetCore2:反序列化忽略带注释的私有字段

protobuf-net 和重复字段

protobuf-net 生成的 .proto 文件中的字段命名约定不正确?

使用 protobuf-net 反序列化具有某些字段的派生类型的对象

如何通过 ProtoBuf-net 使用 DateTimeKind 选项序列化 DateTime 字段