序列化中传递了哪些数据? (二进制序列化)

时间:2009-05-30 09:52:31

标签: c# serialization

在序列化(二进制序列化)中传输什么数据?类(对象)的实例或分配给该对象属性的值。

我想知道序列化过程中发生了什么?我的意思是一个对象被转换为它的目标文件或序列化中的任何东西。但是怎么样?在此过程中遵循了哪些步骤?

有人可以帮忙吗?

...杰

3 个答案:

答案 0 :(得分:5)

Binary Serialization正在快速拍摄对象并将其序列化。这意味着所有未标记为NonSerializable的私有字段都将使用其值进行序列化。 对象层次结构中使用的所有对象必须作为Serializable。 您应该在事件上放置[field:NonSerializable]属性,因此事件处理程序也不会被序列化:http://bytes.com/groups/net-c/250944-nonserialized-attribute-events#post1013968

请记住,在反序列化对象时,必须在序列化对象的同一个程序集中具有完全相同的对象(同样意味着相同的程序集信息)。如果没有,您可以使用SerializationBinder类,这样您就可以重置哪个流将被消毒的类型。

答案 1 :(得分:4)

我认为你的意思是BinaryFormatter;这取决于;-p

序列化的目的是将复杂的内存中对象表示为一个简单的字节序列(或者取决于序列化程序 - 字符等),它们可以在另一端重新水合以重新创建对象。

某些类型(基元,字符串等)由串行器直接支持 - 它直接写入。

对于类,会写入类型元数据(包含程序集名称等),然后枚举类型上的所有字段(基本上是Type.GetFields(),包括私有等)。对于每个字段(未标记为[NonSerialized]),将写入字段名称,并将值序列化(通过相同的过程)。最终,一切都归结为内置的原语,一些类型定义和一些名称/值字段对。

此处的一个例外是类型是否实现ISerializable - 在这种情况下,要求类型将自身序列化为输出。这在字典类型中很常见,其中类型的内存布局可以用不同的方式表示为流。

在反序列化过程中,过程相反; type-metadata用于创建一个空对象(除非它有一个特殊的序列化构造函数/ ISerializable);然后将字段设置为在流中找到它们。

在序列化和反序列化中都有“回调”点,您可以在其中执行其他代码来修复(反)序列化对象。

这个过程很脆弱;由于很多原因,see here - 但它也是版本不容忍和特定于实现的(你不能从java等消费它)。

protobuf-net通过基于合同而非基于字段的二进制序列化器解决了很多这些问题。


答案 2 :(得分:1)

默认情况下,使用二进制序列化时,只会序列化某种类型的字段。属性被视为方法,对序列化没有影响。

使用Xml序列化时,默认情况下会公开属性。