保存对象/序列化

时间:2015-07-02 13:01:25

标签: c#

我正在尝试从C转换到C#,我有一些关于将对象保存到文件和序列化的问题。

在C中,如果你想保存一个数据结构,我已经被教导过将它作为字符串保存为字符串通常是不必要的,而作为内存快照存在的二进制文件通常更好,因为它不是需要编码/解码并将字符串匹配到字段。 在C#中,方法看起来是不同的,它将对象字段分别转换为字符串或其他格式,然后在必要时重新构建对象。我不确定二进制序列化是如何工作的,但我认为它会将数据转换为某种格式,而不是纯粹的非格式化内存快照。

为什么在C#中没有使用任何编码/解码的“内存快照”方法?我能想到的唯一原因是与其他代码和环境的兼容性,也许它与对象与常规结构的复杂性有关。

2 个答案:

答案 0 :(得分:2)

在C#中,您无权访问对象的内存布局。您无法获取对象的内存快照,也无法从快照创建对象。事实上,你甚至没有积分(是的,你有不安全的代码,但你很少编写不安全的代码)。

即使您确实可以访问对象使用的内存,也可能无法保存到磁盘然后重新加载。如果升级.NET环境,您可能会得到一个更好的优化器,它决定以不同的方式重新排序对象的字段,或使用不同的内存对齐。

因此,简而言之 - 无法访问对象内存,因此您需要逐个字段序列化。

好处是,由于.NET具有反射功能,因此以这种方式序列化对象并不难。实际上,它比串行化一个包含指向其他C ++类的指针的C ++类要容易得多。

答案 1 :(得分:1)

.NET二进制序列化格式遵循它们希望如何存储的类型并放入一些元数据中,以便您知道如何解码它(哪种类型,哪个字段名称等)。

这主要不是用于与.NET语言互操作 - 尽管它可能是。它用于与相同对象的过去和未来版本互操作,可以以对这些更改具有弹性的方式编写 - 或者至少知道拒绝它们。

在C中,如果您以任何方式更改结构 - 并且您刚刚使用write()来存储内存,您可能还会选择编写一些元数据,以便您可以知道是否有正确的版本(需要转换)。

另一个好处是.NET语言知道如何处理引用。默认情况下,C会write()一个地址,这在以后就没用了。 .NET还支持不应序列化的字段(如密码)的想法 - 您需要在C版本中手写的另一件事。