目錄:數據庫
24.1 序列化/反序列化快速入門數組
24.2 使類型可序列化服務器
24.3 控制序列化和反序列化網絡
24.4 格式化器如何序列化類型的實例線程
24.5 控制序列化/反序列化的數據設計
24.6 流上下文代理
24.7 類型序列化爲不一樣類型以及對象反序列化爲不一樣對象orm
24.8 序列化代理對象
24.9 反序列化對象時重寫程序集和/或類型繼承
序列化是將對象或對象圖轉換成字節流的過程。反序列化是將字節流轉換回對象圖的過程:
應用程序的狀態(對象圖)可輕鬆保存到磁盤文件或數據庫中,並在應用程序下運行時恢復。ASP.NET就是利用序列化和反序列化來保存和還原會話狀態的。
一組對象可輕鬆複製到系統的剪切板,在粘貼回同一個或另外一個應用程序。
一組對象可克隆並放到一邊做爲「備份」;與此同時,用戶操縱一組「主」對象。
一組對象可輕鬆地經過網絡發送給另外一臺機器上運行的進程。
BinaryFormatter.Serialize序列化
BinaryFormatter.Deserialize反序列化
使用SerializableAttribute定製特性使對象可序列化,特性不會被派生類型繼承。
定義不該序列化的實例字段:
字段含有反序列化後變得無效的信息。如對象包含Windows內核對象(如文件,進程,線程,互斥體,事件,信號量等)的句柄。反序列化到另外一個進程或另外一臺機器以後,就會失去意義。由於Windows內核對象是跟進程相關的值。
字段含有很容易計算的信息。
使用System.NonSerializedAttribute定製特性
格式化器自動序列化類型應用了SerializebleAttribute特性的對象:
1.格式化器調用FormatterServices的GetSerializebleMembers方法:這個方法利用反射獲取類型的public和private實例字段。方法返回由MemberInfo對象構成的數組,其中每一個元素都對應一個可序列化的實例字段。
2.對象被序列化,System.Reflection.MemberInfo對象數組傳給FormatterServices的靜態方法GetObjectData:這個方法返回一個Object數組,其中每一個元素都標識了被序列化的那個對象中的一個字段的值。這個Object數組和MemberInfo數組時並行的。
3.格式化器將程序集標識和類型的完整名稱寫入流。
4.格式化器而後遍歷兩個數組中的元素,將每一個成員的名稱和值寫入流中。
格式化器自動反序列化類型應用了SerializableAttribute特性的對象:
1.格式化器從流中讀取程序集標識和完整類型名稱。若是程序集沒有加載到AppDomain中,就加載它。若是程序集已加載,格式化器將程序集標識信息和類型全名傳給FormatterServices的靜態方法GetTypeFromAssembly:這個方法返回一個System.Type對象,它表明要反序列化的安格對象的類型。
2.格式化器調用FormatterServices的靜態方法GetUninitializedObject:這個方法爲一個新對象分配內存,但不爲對象調用構造器。對象的全部字節都被初始化爲null或0.
3.格式化器如今構造並初始化一個MemberInfo數組,調用FormatterServices的GetSerializableMember方法。這個方法返回序列化好,如今須要反序列化的一組字段。
4.格式化器根據流中包含的數據建立並初始化一個Object數組。
5.將新分配對象,MemberInfo數組以及並行Object數組的引用傳給FormatterServices的靜態方法PopulateObjectMebers:這個方法遍歷數組,將每一個字段初始化成對應的值。
格式化器序列化對象圖時會檢查每一個對象。若是發現一個對象的類型實現了ISerializable接口,就會忽略全部定製特性,改成構造新的System.Runtime.Serialization.SerializationInfo對象。
構造SerializationInfo對象時,格式化器要傳遞兩個參數:Type和System.Runtime.Serialization.IFormatterConverter。Type參數標識要序列化的對象。惟一性地標識一個類型須要兩個部分的信息:類型的字符串名稱及其程序集標識(包括程序集名,版本,語言文化和公鑰)。構造好的SerializationInfo對象包含類型的全名,這個字符串會存儲到一個私有字段中。構造並初始化好SerializationInfo對象後,格式化器調用類型的GetObjectData方法,向它傳遞對SerializationInfo對象的引用。
反序列化:格式化器從流中提取一個對象時,會爲新對象分配內存。最初,這個對象的全部字段都設爲0或null。而後,格式化器檢查類型是否實現了ISerializable接口,若是存在,格式化器就嘗試調用一個特殊構造器,它的參數和GetObjectData方法的徹底一致。構造器獲取一個SerializationInfo對象引用。SerializationInfo對象包含了對象序列化時添加的全部值。
StreamingContext:
成員名稱 | 成員類型 | 說明 |
State | StreamingContextStates | 一組位標識(big flag),指定要序列化/反序列化的對象的來源或目的地 |
Context | Object | 一個對象引用,對象中包含用戶但願的任何上下文信息 |
有的類型設計成每一個AppDomain一個實例。常常將這些類型稱爲單實例類型。
反射類型:每一個類型和程序集或者成員都只能有個實例。
對於遠程控制的對象,CLR序列化與服務器對象有關的信息。
格式化器還容許不是「類型實現的一部分」的代碼重寫該類型「序列化和反序列化其對象」的方式。應用程序之因此重寫(覆蓋)類型的方式:
容許開發人員序列化最初沒有設計成要序列化的類型。
容許開發人員提供一種方式將類型的一個版本映射到類型的一個不一樣的版本。
有時須要將對象反序列化成和序列化時不一樣的類型:
開發人員可能想把一個類型的實現從一個程序集移動到另外一個程序集。
服務器對象序列化到發送給客服端的流中。客服端處理流時,能夠將對象反序列化成徹底不一樣的類型,該類型的代碼知道如何向服務器的對象發出遠程方法調用。
開發人員建立了類型的新版本,想把已序列化的對象反序列化成類型的成類型的新版本。