在序列化(二进制序列化)中传输什么数据?类(对象)的实例或分配给该对象属性的值。
我想知道序列化过程中发生了什么?我的意思是一个对象被转换为它的目标文件或序列化中的任何东西。但是怎么样?在此过程中遵循了哪些步骤?
有人可以帮忙吗?
...杰
答案 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序列化时,默认情况下会公开属性。