標籤:
本節要深入討論一下格式化器如何序列化對象的欄位。掌握了這些知識後,可以更容易地理解本章後面要解釋的一些更進階的序列化和還原序列化技術。
為了簡化格式化器的操作,FCL在System.Runtime.Serialization命名空間提供了一個FormatterServices類型。該類型只包含靜態方法,而且該類型不能執行個體化。以下步驟描述了格式化器如何自動序列化一個應用了SerializableAttribute的對象。
- 格式化器調用FormatterServices的GetSerializableMembers方法:
public static MemberInfo[] GetSerializableMembers(Type type, StreamingContext context);
這個方法利用反射擷取類型的public和private欄位執行個體。方法返回由MemberInfo對象構成的一個數組,其中每個元素都對應於一個可序列化的執行個體欄位。
- 對象被序列化,MemberInfo對象數組傳給FormatterServices的靜態方法GetObjectData,這個方法返回一個Object數組,其中每個元素都標識了被序列化的那個對象中的一個欄位的值。這個Object數組和MemberInfo數組是並行的;換言之,Object數組中的元素0時MemberInfo數組中的元素0所標識的那個成員的值。
- 格式化器將程式集標識和類型的完整名稱寫入流中。
- 格式化器然後遍曆這兩個數組中的元素,將每個成員的名稱和值寫入流中。
以下步驟描述了格式化器如何自動還原序列化一個應用了SerializableAttribute的對象。
- 格式化器從流中讀取程式集和完整類型名稱。如何程式集不能載入,就拋出一個SerializationException異常,對象不能還原序列化。如果程式集已載入,格式化器將程式集標識資訊和類型全名傳給FormatterServices的靜態方法GetTypeFromAssembly,這個方法返回一個System.Type對象,它代表要還原序列化的那個對象的類型。
- 格式化器調用FormatterServices的靜態方法GetUninitializedObject,
這個方法為一個對象分配記憶體,並不為對象調用建構函式。然後對象的所有欄位都被初始化為成null或0.
- 格式化器現在構造並初始化一個MemberInfo數組,具體做法和前面的做法一樣,都是調用FormatterServices的GetSerializableMembers方法。這個方法返回序列化好、現在需要還原序列化的一組欄位。
- 格式化器根據流中包含的資料建立並初始化一個Object數組。
- 將對新分配的對象、MemberInfo數組以及並行Object數組的引用傳給FormatterServices的靜態方法PopulateObjectMembers,這個方法遍曆數組,將每個欄位初始化成對應的值。到此為止,對象就算被徹底還原序列化了。
第四節:格式化器如何序列化類別型執行個體