溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

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

發(fā)布時間:2020-07-05 14:56:26 來源:網(wǎng)絡 閱讀:686 作者:張吉踉 欄目:編程語言

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

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

1.記錄應用程序的狀態(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]特性不支持繼承,該特性標識類中不想被序列化的字段。

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

    那么序列化器如何進行一個類型的具體序列化過程呢?經(jīng)msdn介紹及相關資料查詢得知,這個過程借助于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設置創(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ù)的特殊性,它們設計是被序列化器使用的,為了避免其他人的濫用,最好使用下面的特性

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

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

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

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

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

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

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI