当类型移动了程序集和命名空间时,protobuf-net是否允许向后兼容?

时间:2013-10-29 18:10:24

标签: c# .net serialization protobuf-net backwards-compatibility

我目前很难将DTO从一个程序集和命名空间移动到另一个程序集和命名空间。这是因为我使用二进制序列化来发送/接收数据。在二进制序列化中,契约基本上是程序集名称和类型名称空间+名称。如果将类型移动到不同的程序集,则基本上会破坏合同。

protobuf-net的行为方式是否相同? protobuf-net合同的基础是什么? probuf-net是否允许我将类型从一个程序集移动到另一个程序集而不会破坏向后兼容性?移动命名空间怎么样?

1 个答案:

答案 0 :(得分:3)

这个版本的简短版本是“是的,那将会很好 - 并且就像这样工作是我首先编写它的主要原因之一”。

  

在二进制序列化中,契约基本上是程序集名称和类型命名空间+名称。

这取决于你如何定义“二进制序列化”;如果你的意思是“序列化为恰好是二进制的东西,即非文本”,那么这是无关的。如果你的意思是“基于类型的序列化”,那么:确实 - 这是一个主要的痛点。

  

protobuf-net的行为方式是否相同?

不,它没有。

  

protobuf-net合约的基础是什么?

根本没有描述类型;调用者提供最外层成员的类型,所有其他类型都由类型的布局隐含。

会员仅通过数字键识别; 如果这两个密钥存在于双方(并且它们不一定需要:您可以添加/删除成员),那么它们必须兼容。例如,这些是兼容的:

[ProtoContract]
public class Foo { // in namespace X
    [ProtoMember(1)]
    public int Id {get;set;}
    [ProtoMember(2)]
    public string Name {get;set;}
}
...
[ProtoContract]
public class User { // in namespace Y
    [ProtoMember(2)]
    public string UserName {get;set;}
}

如果序列化Foo然后将其反序列化为User,则字段2中的数据将被推送到UserName(默认情况下,字段1中的数据会被忽略,但可以如果你需要那么存储)。但是,对于Foo

[ProtoContract]
public class BadClass {
    [ProtoMember(2)]
    public double Quantity {get;set;}
}

(这会失败,因为stringdouble的电线类型无法远程比较)

  

probuf-net是否允许我将类型从一个程序集移动到另一个程序集而不会破坏向后兼容性?移动命名空间怎么样?

两者都是。当您考虑可以在C#中进行序列化并在Java或C ++模型中进行反序列化时,它 以这种方式工作。