我目前很难将 DTO 从一个程序集和命名空间移动到另一个程序集和命名空间。这是因为我使用二进制序列化来发送/接收数据。在二进制序列化中,契约基本上是程序集名称和类型命名空间 + 名称。如果您将类型移动到不同的程序集,您基本上违反了合同。
protobuf-net 的行为方式是否相同?protobuf-net 合约的基础是什么?probuf-net 是否允许我在不破坏向后兼容性的情况下将类型从一个程序集移动到另一个程序集?那么移动命名空间呢?
我目前很难将 DTO 从一个程序集和命名空间移动到另一个程序集和命名空间。这是因为我使用二进制序列化来发送/接收数据。在二进制序列化中,契约基本上是程序集名称和类型命名空间 + 名称。如果您将类型移动到不同的程序集,您基本上违反了合同。
protobuf-net 的行为方式是否相同?protobuf-net 合约的基础是什么?probuf-net 是否允许我在不破坏向后兼容性的情况下将类型从一个程序集移动到另一个程序集?那么移动命名空间呢?
简短的版本是“是的,那会很好 - 像这样工作是我首先写它的主要原因之一”。
在二进制序列化中,契约基本上是程序集名称和类型命名空间 + 名称。
这取决于您如何定义“二进制序列化”;如果您的意思是“序列化到恰好是二进制的东西,即非文本”,那么这是不相关的。如果您的意思是“基于类型的序列化”,那么:确实 - 这是一个主要的痛点。
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;}
}
如果将 a 序列化Foo
,然后将其反序列化为 a User
,则将字段 2 中的数据推入UserName
(默认情况下忽略字段 1 中的数据,但如果需要,可以存储)。然而,这不是Foo
:
[ProtoContract]
public class BadClass {
[ProtoMember(2)]
public double Quantity {get;set;}
}
(这将失败,因为 和 的电线类型string
无法double
远程比较)
probuf-net 是否允许我在不破坏向后兼容性的情况下将类型从一个程序集移动到另一个程序集?那么移动命名空间呢?
两者都是。当您考虑可以在 C# 中序列化并在 Java 或 C++ 模型中反序列化时,它必须以这种方式工作。