惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

月光博客
月光博客
Apple Machine Learning Research
Apple Machine Learning Research
IT之家
IT之家
阮一峰的网络日志
阮一峰的网络日志
雷峰网
雷峰网
S
SegmentFault 最新的问题
量子位
有赞技术团队
有赞技术团队
V
V2EX
宝玉的分享
宝玉的分享
Hugging Face - Blog
Hugging Face - Blog
B
Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Jina AI
Jina AI
C
Check Point Blog
G
Google Developers Blog
博客园 - 叶小钗
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园_首页
T
Tailwind CSS Blog
B
Blog RSS Feed
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
酷 壳 – CoolShell
酷 壳 – CoolShell
U
Unit 42

博客园 - bengxia

DataGridView中的{索引-1沒有值}异常 Silverlight + WCF + Sharepoint(Silverlight Web Part) 问题集合 CLR Via C# 3rd 阅读摘要 -- Chapter 29 – Hybrid Thread Synchronization Constructs CLR Via C# 3rd 阅读摘要 -- Chapter 28 – Primitive Thread Synchronization Constructs FIX: Unable to find a version of the runtime to run this application. CLR Via C# 3rd 阅读摘要 -- Chapter 27 – I/O-Bound Asynchronous Operations CLR Via C# 3rd 阅读摘要 -- Chapter 26 – Compute-Bound Asynchronous Operations CLR Via C# 3rd 阅读摘要 -- Chapter 25 – Thread Basics CLR Via C# 3rd 阅读摘要 -- Chapter 23 – Assembly Loading and Reflection CLR Via C# 3rd 阅读摘要 -- Chapter 22 – CLR Hosting and AppDomains CLR Via C# 3rd 阅读摘要 -- Chapter 21 – Automatic Memory Management (Garbage Collection) CLR Via C# 3rd 阅读摘要 -- Chapter 20 – Exceptions and State Management - bengxia CLR Via C# 3rd 阅读摘要 -- Chapter 19 – Nullable Value Types CLR Via C# 3rd 阅读摘要 -- Chapter 18 - Custom Attributes CLR Via C# 3rd 阅读摘要 -- Chapter 17 - Delegates CLR Via C# 3rd 阅读摘要 -- Chapter 16 - Arrays - bengxia CLR Via C# 3rd 阅读摘要 -- Chapter 15 - Enumerated Types and Bit Flags CLR Via C# 3rd 阅读摘要 -- Chapter 14 - Chars, Strings, and Working with Text CLR Via C# 3rd 阅读摘要 -- Chapter 13 - Interfaces
CLR Via C# 3rd 阅读摘要 -- Chapter 24 – Runtime Serializa...
bengxia · 2010-05-31 · via 博客园 - bengxia

Serialization/Deserialization Quick Start

  1. 序列化是将一个对象以及相关的对象转换成字节流的过程;反序列化就是序列化的逆过程;
  2. System.Runtime.Serialization命名空间;
  3. 当序列化一个对象时,Formatter首先抓取程序集标识,并确定程序集通过调用System.Reflection.Assembly.Load()被装载到执行的AppDomain中;
  4. 程序集被装载后,Formatter在程序集中查找待反序列化对象所匹配的类型,然后实例化再根据流来初始化实例的字段;
  5. 一些扩展程序使用Assembly.LoadFrom()来加载程序集,然后从定义在程序集中的类型来构造对象。这些对象在序列化时没有问题,但是反序列化时,Formatter会尝试使用Assembly.Load()来加载程序集,大多数情况下,CLR不能准确定位程序集文件,所以可能会引发SerializationException;
  6. 因为上面的原因,如果使用Assembly.LoadFrom()来加载程序集,那么强烈建议在反序列化之前处理System.AppDomain.AssemblyResolver事件。

Making a Type Serializable

  1. 对象在默认情况下是不能序列化的,可以通过给类型加上[Serializable]标签来实现;
  2. [Serializable]属性不能被子类型所继承;
  3. System.Object有[Serializable]属性;
  4. 一般来说,推荐大多数类型为可序列化的?(我的看法是那些可能会被跨边界访问的类型)。

Controlling Serialization and Deserialization

  1. 至少有两个原因使得你不打算让类型实例的一些字段被序列化:
    • 字段的值在反序列化时已经失效了,比如Windows Kernel对象的句柄(文件、进程、线程、互斥体、事件、信号量、……);
    • 字段的值可以在反序列化时很简单的重新计算出来。
  2. 字段加上[NonSerialized]属性标签可以阻止该字段被序列化;
  3. 如果希望字段在反序列化时被重新计算,可以定义一个方法[OnDeserialized]private void OnDeserialized(StreamingContext context){...}
  4. 跟[OnDeserialized]相似的几个属性[OnSerializing] -> [OnSerialized] -> [OnDeserializing] -> [OnDeserialized];
  5. 如果你序列化一个类型的实例,在类型中加入新的字段,然后在尝试反序列化时,Formatter会抛出SerializationException指出成员数目不对,可以通过使用[OptionalField]属性标签来解决该问题。

How Formatters Serialize Type Instances

  1. FormatterServices.GetSerializableMembers(), .GetObjectData(), GetTypeFromAssembly(), GetUninitializedObject(), .PopulateObjectMembers()静态方法。

Controlling the Serialized/Deserialized Data

  1. 如何完全的控制序列化/反序列化,可以实现System.Runtime.Serialization.ISerializable接口;
  2. 一旦类型继承了ISerializable接口,那么子类型也就必须实现该接口;
  3. 建议在GetObjectData方法和特殊构造器上附加[SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)]属性标签;
  4. 当Formatter在序列化对象图时,先查找每一个对象,如果有一个类型实现了ISerializable接口,Formatter就忽略其他所有的客户属性,并构造一个新的System.Runtime.Serialization.SerializationInfo对象;
  5. 总是调用SerializationInfo.AddValue来加入序列化信息到类型中,如果字段的类型实现了ISerializable接口,别在字段上调用GetObjectData,而是调用AddValue;
  6. 如果类型是sealed,那么强烈建议将特殊构造声明为private;
  7. 如果基类没有实现ISerializable接口,怎样为类型实现该接口?FormatterServices.GetSerializableMembers()。

Streaming Contexts

  1. StreamingContext.State, .Context;
  2. StreamingContextStates {CrossProcess, CrossMachines, File, Persistence, Remoting, Other, Clone, CrossAppDomain, All};

Serializing a Type as a Different Type and Deserializing an Object as a Different Object

Serialization Surrogates

  1. System.Runtime.Serialization.ISerializationSurrogate.GetObjectData(), .SetObjectData();
  2. BinaryFormatter有一个bug阻止从序列化对象到其他的引用。要解决该问题,需要传一个ISerializationSurrogate对象的引用到FormatterServices.GetSurrogateForCyclicalReference()方法;
  3. SurrogateSelector.AddSurrogate(),多个SurrogateSelector对象可以被链接起来,SurrogateSelector实现了ISurrogateSelector接口。

Overriding the Assembly and/or Type When Deserializing an Object

  1. System.Runtime.Serialization.SerializationBinder使得反序列化对象到不同的类型非常容易。要做到这点,需要定义的类型继承自抽象类SerializationBinder。

本章小结

   本章讲了序列化和反序列化的知识,序列化可以讲对象转换成流进行传输或者持久化,在需要的时候通过反序列化在将对象构造出来。首先讲了如何让类型具备序列化的能力,以及如何控制序列化的过程。然后讲了Formatter如何序列化类型实例,如何控制序列化/反序列化的数据,介绍了StreamingContext对象,演示了如何将对象反序列化到不同的类型实例。接着介绍了序列化代理,最后讲了SerializationBinder抽象类可以用来反序列化对象到不同的类型。