2

我有一个库(用 C# 编写),我需要将我的对象的表示以特定的二进制格式读/写到磁盘(或任何流)(以确保与 C/Java 库实现的兼容性)。该格式需要大量的位打包和一些 DEFLATE 字节流。但是,我希望我的库尽可能地使用惯用的 .NET,因此希望提供一个尽可能接近正常二进制序列化过程的 API。我知道实现 IFormatter 接口的能力,但是由于我真的无法重用内置序列化堆栈的任何部分,是否值得这样做,或者它只会带来不必要的开销。换句话说:

实施 IFormatter 和合作。

或者

只提供作用于流的“序列化”/“反序列化”方法?


下面提出了一个很好的观点,即在涉及远程处理的任何情况下都需要序列化语义。在使用 MarshalByRef 对象可行的情况下,我很确定这不会成为问题,所以撇开这一点不谈,使用 ISerializable/IFormatter 与自定义堆栈相比有什么好处或坏处(或者,我的理解是远程错误)?

4

3 回答 3

0

我总是选择后者。如果您所做的只是将文件写入特定框架,那么重用序列化框架没有多大用处。我在使用自定义序列化框架时遇到的唯一问题是在远程处理时,您必须使对象可序列化。

这可能对您没有帮助,因为您必须写入特定格式,但 protobuf 和 sqlite 是进行自定义序列化的好工具。

于 2009-07-05T12:46:19.273 回答
0

我会做前者。界面没有太多内容,因此如果您要模仿结构,无论如何添加一个“ : IFormatter”,并且获得完全兼容性所需的其他代码不会花费太多。

于 2009-07-05T13:11:03.030 回答
0

编写自己的序列化代码容易出错且耗时。

作为一个想法 - 您是否考虑过现有的开源可移植格式,例如“协议缓冲区”?这是一种高密度二进制序列化格式,支持 Google 的大部分数据传输等。版本可用于多种语言 - 包括 Java/C++ 等(在核心 Google 发行版中),以及大量其他语言。

特别是,对于 .NET 惯用用法,protobuf-net看起来很像XmlSerializeror (实际上,DataContractSerializer如果它在每个元素上包含一个顺序,它甚至可以纯粹使用 xml/wcf 属性) - 或者可以使用特定的 protobuf-net 属性:

[ProtoContract]
class Person {
    [ProtoMember(1)]
    public string Name {get;set;}
}

如果您想保证对其他实现的可移植性,建议使用“.proto”文件启动“合同优先” - 在这种情况下,类似于:

message person {
    required string name = 1;
}

然后可以使用此 .proto 文件生成任何特定于语言的变体;因此,使用 protobuf-net,您可以通过“protogen”运行它(包含在 protobuf-net 中;并且正在进行 VS2008 附加组件);或者对于 Java/C++ 等,您可以通过“protoc”(包含在 Google 的 protobuf 中)运行它。protobuf-net 中的“protogen”目前可以发出 C# 和 VB,但如果你想使用 F# 等,添加另一种语言非常容易——它只涉及编写(或迁移)一个 xslt。

还有另一个 .NET 版本,它是 Java 版本的更直接端口;因此,它不太符合 .NET 习惯。这是dotnet-protobufs

于 2009-07-05T19:30:09.533 回答