代码之家  ›  专栏  ›  技术社区  ›  Matt Enright

如何模仿内置的。NET序列化习语?

  •  2
  • Matt Enright  · 技术社区  · 15 年前

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

    实现IFormatter和co。

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


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

    3 回复  |  直到 15 年前
        1
  •  0
  •   Michael Hedgpeth    15 年前

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

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

        2
  •  0
  •   Joel Coehoorn    15 年前

    我会选择前者。界面上没有太多东西,所以如果你在模仿结构的话,添加一个“ : IFormatter “而获得完全兼容性所需的其他代码也不会花费太多时间。

        3
  •  0
  •   Marc Gravell    15 年前

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

    作为一个想法——例如,您是否考虑过现有的开源便携格式?” protocol buffers “?这是一种高密度二进制序列化格式,支持谷歌的大部分数据传输等。版本有多种语言,包括Java/C++等(在谷歌核心发行版中),以及 vast range of others .

    尤其是对于。NET惯用用法, protobuf-net 看起来像 大量 喜欢 XmlSerializer 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”(包含在谷歌的protobuf中)运行它。protobuf net中的“protogen”目前可以发出C#和VB,但如果您想使用F#等,添加另一种语言是相当容易的——它只需要编写(或迁移)xslt。

    还有一个。NET版本,它是Java版本的一个更直接的端口;就其本身而言,它就不那么重要了。NET的惯用用法。这是 dotnet-protobufs .