可序列化類型定義-serializable
類型前面添加了[serializable]特性的類就是可序列化類型,SerializableAttribute特性只能應用於引用類型(class)、值類型(struct)、枚舉類型(enum)和委托類型(delegate)。枚舉和委托類型總是可序列化的所以不必顯示使用SerializableAttribute特性。所有不用添加[serializable]特性。
序列化必須使用到序列化器。
設計類型時,設計人員必須鄭重地決定是否允許類型的實例序列化。類型默認是不可序列化的。開發者必須向類型應用定制特性system.serializableAttribute。任何對象不可序列化,格式化器的serialize方法都會拋出異常。
注意:考慮到性能,在序列化之前,格式化器不會驗證對象圖中的所有對象都能序列化。所以在拋出異常之前,完全有可能已經有一部分對象序列化到流中。如果發生這種情況,流中就會包含已損壞的數據。
soap序列化器:可以對單個對象進行序列化。但是,很大的缺陷在於,不能直接對泛型集合數據(如List<T>、ObservableCollection<T>)進行序列化(注:無論是根對象就是泛型集合,還是某個對象下的字段或屬性是泛型集合,都不能序列化),
而要使用BinaryFormatter或XmlSerializer進行序列化。由於無法對泛型集合對象進行序列化,因此使用面比較窄,個人不建議使用SoapFormatter
XML序列化器:可以對單個對象或集合對象(如List<T>、ObservableCollection<T>)進行序列化。需要指出的是,需要對被序列化的對象添加[Serializable]特性
Json序列化:目前業界,普通都采用此方式,優點很多
BinaryFormatter 以及過時。由於 類型會帶來風險,不建議將其用於數據處理。 即使應用程序認為自己正在處理的數據是可信的,也應盡快停止使用 BinaryFormatter
。 BinaryFormatter
不安全,無法確保安全。
繼承性
[serializeable] 不會遺傳到子類,如果子類標記為[serializeable],那么基類也必須標記[serializeable]。因為子類保護了父類。
公開性
序列化會讀取對象的所有字段保存成二進制,不管這些字段聲明為public,protercted,private、internal還是readonly。 因此敏感的數據例如賬號密碼等字段應該設置成不可序列化[Noserializeable]。
序列化控制
可以使用:[Noserializeable]、[Noserializeable]、[OptionalField]、[OnDeserializing]、[OnSerialized]、[OnSerializing]特性對序列化進行部分控制。
[Noserializeable]: 定義不進行序列化的部分。
1、敏感的數據例如賬號密碼等字段應該設置成不可序列化[Noserializeable]。
2、內核對象(線程 、進程、線程、互斥體、事件、信號量)的句柄,那么在反序列化到另一個進程或者另一台機器之后,就會失去意義。因為windows 內核對象跟進程相關。
3、字段含有很容易計算的信息。主要為了減少數據傳。
[Serializable] public class DIYClass { public DIYClass() { x = 10; y = 100; z = 1000; } public int x { get; set; } public int y { get; set; } [NonSerialized] public int z; }
在序列化之前,該自定義對象 z 字段的值為 1000,在序列化時,檢測到了忽略特性,則不會寫入該字段的值到流當中。並且在反序列化之后,z 的值為 0,而 x ,y 的值是 10 和 100。
如有可能,應使可能包含安全敏感數據的對象不可序列化。 如果必須序列化該對象,則可將 NonSerialized
屬性應用於存儲敏感數據的特定字段。 如果沒有將這些字段排除在序列化之外,應該注意字段存儲的數據會向有權序列化的所有代碼公開。 有關編寫安全的序列化代碼的詳細信息,請參閱安全和序列化。
[OptionalFiled]:類型新增字段時,新增的每個字段應該添加該屬性,當格式化器看到該特性應用於一個字段時,就不會因為流中的數據不包含這個字段而拋出SerializtionException.
[OnDeserialized]:在反序列化后期運行,序列化后給字段賦值。
[OnDeserializing]:在反序列化時運行,反序列化時候修改字段值。
[OnSerialized]:在序列化完成后運行,詳單與在初始化時候賦值。
[OnSerializing]:在序列化時運行,相當於初始化之后賦值。
序列化執行順序:1、序列化一組對象時,格式化器首先調用對象的標記了OnSerializing特性的所有方法。
2、接着,它序列化對象的所有字段。
3、最后調用對象的標記了OnSerialized特性的所有方法。
反序列化執行順序:1、反序列化一組對象時,格式化器會將這個對象的引用添加到一個內部列表中
2、反序列化一組對象時,格式化器首先調用對象的標記了OnDeSerializing特性的所有方法。
3、接着,它序反列化對象的所有字段。
4、最后調用對象的標記了OnDeSerialized特性的所有方法。
5、反向調用 格式化器內部的列表,調用每個對象的OnDeSerialized方法,這個方法被調用后,之所以要方向調用,因為這樣才能使內存的對象優於外層對象。