.NET序列化反序列化總結(jié)

   一直想寫這個專題,但是工作后人很懶散,總下不了決心,今天一個人在家就寫下來。

創(chuàng)新互聯(lián)公司專注于網(wǎng)站制作、成都網(wǎng)站制作、網(wǎng)頁設(shè)計、網(wǎng)站制作、網(wǎng)站開發(fā)。公司秉持“客戶至上,用心服務(wù)”的宗旨,從客戶的利益和觀點出發(fā),讓客戶在網(wǎng)絡(luò)營銷中找到自己的駐足之地。尊重和關(guān)懷每一位客戶,用嚴謹?shù)膽B(tài)度對待客戶,用專業(yè)的服務(wù)創(chuàng)造價值,成為客戶值得信賴的朋友,為客戶解除后顧之憂。

   關(guān)于序列化,可以總結(jié)出它的作用有以下幾點:

1.記錄應(yīng)用程序的狀態(tài),在下次啟動時還原上次的狀態(tài)。

2.進程之間的通信,如使用socket編程時使用。這里的進程包括同一臺主機之間進程的通信,也包括不同主機之間的通信。

3.作為對象的深拷貝的一種實現(xiàn)方式。

      .net中的序列化支持下面幾種序列化機制:

1.使可序列化的類型序列化和反序列化

2.控制可序列化的類型的序列化/反序列化內(nèi)容和過程

3.將類型序列化/反序列化為不同的類型

4.使用代理序列化/反序列化原本不可序列化的類型

      要想一個類型可序列化,只需要在定義這個類型時為它加上一個[Serializable]特性既可,如下:

[Serializable]
public class ClassA
{
   private float x; 
   private float y; 
   [NonSerialized]   
   private float area; 
}

 這樣,類型A即支持序列化了。.net序列化規(guī)則有如下特點:枚舉和委托自動支持序列化,序列化特性不支持繼承,因此如果在定義另一個類B繼承ClassA時,不顯示為類B加上序列化特性,那么類B是不支持序列化的,即[Serializable]支持繼承,然而[NonSerialized]特性不支持繼承,該特性標識類中不想被序列化的字段。

     如何控制序列化、反序列化的過程。在類中的相關(guān)方法上加上[OnSerializing],[OnSerialized],[OnDeserializing],[OnDesirialized]特性用于控制類型在序列化之前,序列化之后,反序列之前,反序列化之后要做的工作。

    那么序列化器如何進行一個類型的具體序列化過程呢?經(jīng)msdn介紹及相關(guān)資料查詢得知,這個過程借助于System.Runtime.Serialization.FormatterServices這個類型,具體步驟如下:

(1)獲取類型的序列化字段,標識了[NonSerialized]特性的字段除外。這個過程通過調(diào)用

     FormatterServices類型的GetSerializableMembers方法完成。

(2)獲取類型需要序列化的字段的值。調(diào)用FormaterServices類型的GetObjectData方法完成。

(3)寫入程序集的標識和類型的完整標識。

(4)寫入步驟2獲取的值到流中,完成序列化過程。

     反序列化的具體步驟:

(1)根據(jù)序列化進流中的程序集標識和類型標識,創(chuàng)建反序列化類型的Type,調(diào)用GetTypeFromAssembly

     方法完成

(2)根據(jù)獲得的Type調(diào)用GetUnitializedObject方法創(chuàng)建反序列化的對象,這個過程不通過構(gòu)造器完成,所有字段全部被初始化為0或null.

(3)獲得類型的序列化字段集合。

(4)根據(jù)流中的字段值構(gòu)造字段值的集合。

(5)調(diào)用PopulateObjectMembers設(shè)置創(chuàng)建的對象的值。

    如何精細控制序列化、反序列化的內(nèi)容呢?比如我們想序列化這個類型時不只是簡單的的序列化那些字段的值,而是這個基于字段值的一個函數(shù)值,怎么實現(xiàn)呢?通過實現(xiàn)接口ISerializable來完成。

interface ISerializable
{
   void GetObjectData(SerializationInfo info,StreamingContext context)
}

   在GetObjectData方法中添加任何我們想要序列化的內(nèi)容。一般來說,除實現(xiàn)這個接口外,我們還需要實現(xiàn)一個特殊的構(gòu)造器,這個構(gòu)造器用于在反序列化時設(shè)置類型的字段值。由于這兩個函數(shù)的特殊性,它們設(shè)計是被序列化器使用的,為了避免其他人的濫用,最好使用下面的特性

[SecurityPermissionAttribute(SecurityAction.Demond,SerializationFormatter=true)]

序列化器在序列化一個類型時如果發(fā)現(xiàn)類型實現(xiàn)了改接口,則會忽略應(yīng)用與字段的特性值,改為調(diào)用該接口的GetObjectData方法,設(shè)置實際需要序列化的值。

     將對象序列化為不同的類型或者將對象反序列化不同的類型,該怎么實現(xiàn)呢?一般來說,我們讓該對象實現(xiàn)ISerializable接口,在GetObjectData方法中通過調(diào)用SerializationInfo的SetType設(shè)置新的對象即可,而這個對象實現(xiàn)IObjectReference接口。

   上面這些序列化技術(shù)都是在我們能修改類型的源代碼的情況下進行的,那么當我們不能修改類型的源代碼或者這個類型開始并沒有設(shè)計為可序列化時,我們想序列化它怎么辦?通過.NET提供的序列化代理技術(shù)可以解決這個問題,序列化代理必須實現(xiàn)下面這個接口:

interface ISerializationSurrogate
{
     void SetObjectData(object obj,SerializationInfo info,StreamingContext context);
     void GetObjectData(object obj,SerializationInfo info,StreamingContext context);  
}

GetObjectData方法用于設(shè)置你想序列化的數(shù)據(jù),obj為你想序列化的類型,SetObjectData為反序列化時調(diào)用的方法,在這里你可以進行對類型進行初始化。至于使用代理的具體步驟,查詢MSDN吧!

網(wǎng)站標題:.NET序列化反序列化總結(jié)
本文來源:http://muchs.cn/article36/jcpisg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供虛擬主機、網(wǎng)站設(shè)計網(wǎng)站策劃、App設(shè)計網(wǎng)站改版、網(wǎng)站導航

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

小程序開發(fā)