Serializable在C#中的做用.net中的對象序列化 (轉)

序列化是指將對象實例的狀態存儲到存儲媒體的過程,在此過程當中,先將對象的公共字段和私有字段以及類的名稱(包括類所在的程序集)轉程序員

換爲字節流,而後再把字節流寫入數據流,在隨後對對象進行反序列化時,將建立出與原對象徹底相同的副本。框架

 

在面向對象的環境中實現序列化機制時,必須在易用性和靈活性之間進行一些權衡。只要您對此過程有足夠的控制能力,就可使該過程在很大程度上自動進行。例如,簡單的二進制序列化不能知足須要,或者,因爲特定緣由須要肯定類中那些字段須要序列化。如下各部分將探討 .NET 框架提供的可靠的序列化機制,並着重介紹使您能夠根據須要自定義序列化過程的一些重要功能。函數

 

持久存儲 咱們常常須要將對象的字段值保存到磁盤中,並在之後檢索此數據。儘管不使用序列化也能完成這項工做,但這種方法一般很繁瑣並且容易出錯,而且在須要跟蹤對象的層次結構時,會變得愈來愈複雜。能夠想象一下編寫包含大量對象的大型業務應用程序的情形,程序員不得不爲每個對象編寫代碼,以便將字段和屬性保存至磁盤以及從磁盤還原這些字段和屬性。序列化提供了輕鬆實現這個目標的快捷方法。工具

 

公共語言運行時 (CLR) 管理對象在內存中的分佈,.NET 框架則經過使用反射提供自動的序列化機制。對象序列化後,類的名稱、程序集以及類實例的全部數據成員均被寫入存儲媒體中。對象一般用成員變量來存儲對其餘實例的引用。類序列化後,序列化引擎將跟蹤全部已序列化的引用對象,以確保同一對象不被序列化屢次。.NET 框架所提供的序列化體系結構能夠自動正確處理對象圖表和循環引用。對對象圖表的惟一要求是,由正在進行序列化的對象所引用的全部對象都必須標記爲 Serializable(請參閱基本序列化)。不然,當序列化程序試圖序列化未標記的對象時將會出現異常。性能

當反序列化已序列化的類時,將從新建立該類,並自動還原全部數據成員的值。.net

 

按值封送 對象僅在建立對象的應用程序域中有效。除非對象是從 MarshalByRefObject 派生獲得或標記爲 Serializable,不然,任何將對象做爲參數傳遞或將其做爲結果返回的嘗試都將失敗。若是對象標記爲 Serializable,則該對象將被自動序列化,並從一個應用程序域傳輸至另外一個應用程序域,而後進行反序列化,從而在第二個應用程序域中產生出該對象的一個精確副本。此過程一般稱爲按值封送。代理

 

若是對象是從 MarshalByRefObject 派生獲得,則從一個應用程序域傳遞至另外一個應用程序域的是對象引用,而不是對象自己。也能夠將從 MarshalByRefObject 派生獲得的對象標記爲 Serializable。遠程使用此對象時,負責進行序列化並已預先配置爲 SurrogateSelector 的格式化程序將控制序列化過程,並用一個代理替換全部從 MarshalByRefObject 派生獲得的對象。若是沒有預先配置爲 SurrogateSelector,序列化體系結構將聽從下面的標準序列化規則(請參閱序列化過程的步驟)。orm

 

 

基本序列化對象

 

要使一個類可序列化,最簡單的方法是使用 Serializable 屬性對它進行標記,以下所示:內存

 

[Serializable] public class MyObject {    public int n1 = 0;    public int n2 = 0;    public String str = null; } 如下代碼片斷說明了如何將此類的一個實例序列化爲一個文件:

MyObject obj = new MyObject(); obj.n1 = 1; obj.n2 = 24; obj.str = "一些字符串"; IFormatter formatter = new BinaryFormatter(); Stream stream = new FileStream("MyFile.bin", FileMode.Create, FileAccess.Write, FileShare.None); formatter.Serialize(stream, obj); stream.Close(); 本例使用二進制格式化程序進行序列化。您只需建立一個要使用的流和格式化程序的實例,而後調用格式化程序的 Serialize 方法。流和要序列化的對象實例做爲參數提供給此調用。類中的全部成員變量(甚至標記爲 private 的變量)都將被序列化,但這一點在本例中未明確體現出來。在這一點上,二進制序列化不一樣於只序列化公共字段的 XML 序列化程序。

將對象還原到它之前的狀態也很是容易。首先,建立格式化程序和流以進行讀取,而後讓格式化程序對對象進行反序列化。如下代碼片斷說明了如何進行此操做。

IFormatter formatter = new BinaryFormatter(); Stream stream = new FileStream("MyFile.bin", FileMode.Open,FileAccess.Read,FileShare.Read);

Myobject obj =(Myobject)formatter.Deserialize(stream);

stream.close()

Console.WriteLine("n1:{0}",obj.n1);

 

上面使用的BinaryFormatter效率很高,能生成很是緊湊的字節流,全部使用此格式化程序序列化的對象也可使用它進行反序列化,對於序列化將在.net平臺上進行反序列化的對象,此格式化程序無疑是一個理想工具,須要注意的是:對對象進行反序列化時並不調用構造函數,對反序列化添加這項約束,是出於性能方面的考慮,可是,這違反了對象編寫者一般採用的一些運行時約定,所以,開發人員在將對象標記爲

可序列化時,應確保考慮了這一特殊約定。

相關文章
相關標籤/搜索