【问题标题】:Why does DataContractSerializer not implement IFormatter?为什么 DataContractSerializer 不实现 IFormatter?
【发布时间】:2009-12-26 20:38:36
【问题描述】:

我对 .NET 中不同形式的序列化缺乏一致性感到有些沮丧:

  • DataContractSerializer - 使用新的属性或旧的 [Serializable] 属性,但序列化程序本身并没有实现 IFormatter,而其他一些 WCF 序列化程序会这样做。选择加入。

  • NetDataContractSerializer - 使用新属性或旧属性,序列化程序实现 IFormatter,与 WCF 兼容,并且是 Opt IN。似乎是理想的解决方案!

  • XmlSerializer - 完全独立的属性集,但是是遗留的,所以可以原谅。

  • BinaryFormatter - 实现 IFormatter 并使用 [Serializable] 属性。选择退出。

所以我的问题是,为什么 DataContractSerializer 不能与 BinaryFormatter 保持至少相当的可互换性?

我真的希望他们从一开始就为此选择了一个干净整洁的界面,对于通常如此有序的 .NET 框架来说,这真是太可惜了!

编辑:仅针对那些感兴趣的人(我知道这与该主题的其余部分并不真正相关),我一直在对我认为最有可能“在场”的内容进行时间和规模基准测试wire" 序列化方法:

============ Serialization ============

Protobuf     x158,194 39,549 per/sec  1.00
OldFieldbase  x58,191 14,548 per/sec  2.72
Fieldbase     x57,445 14,361 per/sec  2.75
DataContract  x54,611 13,653 per/sec  2.90
Binary        x29,466  7,367 per/sec  5.37
Net           x28,170  7,043 per/sec  5.62
Json          x10,605  2,651 per/sec 14.92

和尺寸:

============ SerializationSizes ============

Protobuffers  209 bytes 1.00
Fieldbase     246 bytes 1.18
OldFieldbase  248 bytes 1.19
Json          728 bytes 3.48
DataContract 1227 bytes 5.87
Net          1658 bytes 7.93
Binary       1826 bytes 8.74

注意:在 Core2 T9300(单线程)+ 4GB 上。

【问题讨论】:

    标签: .net wcf serialization


    【解决方案1】:

    我能想到 DataContractSerializer 没有实现 IFormatter 的两个可能原因:

    • 性能 - DCS 经过专门调整以尽可能快,因为 WCF 严重且频繁地依赖对象序列化/反序列化 - 这是 DCS 不支持的原因之一,例如XML节点上的属性;总而言之,它比 XmlSerializer 快 10% 左右

    • 互操作性 - 请记住,WCF 从一开始就是为了尽可能地具有互操作性 - 不仅仅是 .NET 到 .NET,还可以与任意数量的其他系统互操作,例如 Java、Ruby、 - 你的名字; BinaryFormatter、XmlSerializer 和 NetDataContractSerializer 都不能在可互操作的场景中使用 - 它们都是 .NET 特定的,并且只能从 .NET 获得和使用

    这是一个常见问题 - 许多 .NET 开发人员只是简单地忘记了 WCF 不是 .NET 特定且仅 .NET 的技术 - 它必须努力保持尽可能多的兼容性其他系统可能无法提供 .NET 的所有功能。另一个恰当的例子是 WCF 中的错误处理 - 不要只是抛出 .NET 异常 - 这些是 .NET 特定的,对 Java 客户端没有任何意义 - 在 WCF 服务中使用 SOAP 错误! (除非您可以 100% 确定非 .NET 客户端不会永远调用您的服务)

    【讨论】:

    • 关于抛出错误等的所有优点。根据我的经验,尽管让 WCF 与 Metro 或 Axis 等工具一起工作仍然是一件非常痛苦的事情——有什么建议吗?我将在稍后发布一些我运行的基准测试结果作为问题的一部分。即使考虑到您的观点,尽管我不相信这些足以让他们避免实施 IFormatter - 您的观点都是实施细节。
    • 我不是 Indigo 设计团队的成员,所以我真的不知道他们为什么选择不实施 IFormatter - 我只是根据我对 WCF 及其工作原理(以及如何一些 .NET 开发人员有时会误用它)
    【解决方案2】:

    DataContract 序列化使用 opt-in 策略,您必须显式标记成员以进行序列化,默认情况下不序列化成员。使用 [Serializable] 属性的序列化使用 opt-out 策略,其中 [Serializable] 对象的所有成员默认情况下都会被序列化,除非标记为 [NonSerialized]。

    这是为了防止通过向数据合同对象添加字段或属性来防止意外修改数据合同。

    【讨论】:

    • 授予 - 这是一个原因,我可以看到这是引入新的 [DataContract] 等属性的一个很好的理由,但我认为不需要一个全新的类结构来反对格式化程序。例如,NetDataContractSerializer 遵循 DataContractSerializer,但实现了 IFormatter。为什么会这样?
    猜你喜欢
    • 1970-01-01
    • 2010-10-25
    • 2011-08-29
    • 1970-01-01
    • 2011-05-01
    • 2011-08-20
    • 1970-01-01
    • 2020-05-18
    • 2017-02-09
    相关资源
    最近更新 更多