第七節:將類型序列化為不同的類型以及將類型還原序列化為不同的對象

來源:互聯網
上載者:User

標籤:

.NET Framework的序列化架構相當全面,本節要討論如何設計一個類型,本節要討論如何設計一個類型,它能將自己的序列化或還原序列化成一個不同的類型或對象。下面列舉一些有趣的例子。

1、         有的類型(比如System.DBNull和System.Reflection.Missing)設計成每個AppDomain一個執行個體。我們經常把這些類型稱為單一實例類型。給定一個DBNull對象引用,序列化和還原序列化它不應造成在AppDomain中建立一個DBNull對象。序列化後,返回的引用應指向AppDomain中現有的DBNull對象。

2、         對於某些類型來說(比如System.Type,System.Reflection.Assembly和其他反射類型,比如MemberInfo),每個類型、每個程式集或每個成員等只有一個執行個體。例如,假定一個數組中的每個元素都引用一個MemberInfo對象,其中有5個元素都引用一個MemberInfo對象。在序列化和還原序列化這個數組之後,當初引用一個MemberInfo對象的5個元素現在還是應該引用一個MemberInfo對象。除此之外,這些元素引用的那個MemberInfo對象還必須實際對應於AppDomain中的一個特定的成員。在輪詢資料庫連接對象或者其他任何類型的對象時,也可以利用這個單一實例功能。

3、         對於遠端控制的對象,CLR序列化與伺服器對象有關的資訊。在用戶端上還原序列化時,會造成CLR建立一個代理對象。這個代理對象的類型有別於伺服器對象的類型,但這對於用戶端代碼來說是透明的。用戶端直接在代理對象上調用執行個體方法。然後,代理代碼內部會將調用遠程發送給伺服器,有後者實際執行請求的操作。

下面來看看一些範例程式碼,他們展示了如何正確序列化和還原序列化一個單一實例類型:

[Serializable]    public sealed class Singleton : ISerializable    {        private static readonly Singleton s_theOneObject = new Singleton();        public string Name = "Jeff";        public DateTime date = DateTime.Now;        //        private Singleton() { }        public static Singleton GetSingleton()        {            return s_theOneObject;        }        [SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]        void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)        {            info.SetType(typeof(SingleSerializationHelper));        }        [Serializable]        private sealed class SingleSerializationHelper : IObjectReference        {            //這個方法在對象還原序列化之後調用            public Object GetRealObject(StreamingContext context)            {                return Singleton.GetSingleton();            }        }    }

Singleton類所代表的類型規定每個AppDomain只能存在它自己的一個執行個體。以下代碼測試Singleton的序列化和還原序列化代碼,保證AppDomain中存在Singleton類型的一個執行個體:

  private static void SingletonSerializationTest()        {            Singleton[] a1 = { Singleton.GetSingleton(), Singleton.GetSingleton() };            Console.WriteLine("do both elements refer to the same object ?" + (a1[0] == a1[1]));//true            using (var stream = new MemoryStream())            {                BinaryFormatter formatter = new BinaryFormatter();                formatter.Serialize(stream, a1);                stream.Position = 0;                Singleton[] a2 = (Singleton[])formatter.Deserialize(stream);                Console.WriteLine("do both elements refer to the same object ?" + (a2[0] == a2[1]));//true                Console.WriteLine("do both elements refer to the same object ?" + (a2[0] == a2[0]));//true            }        }

現在,我們通過分析代碼來理解所發生的事情。Singleton類型載入到AppDomain中時,CLR調用它的靜態構造器,它構造一個對象,並將對象的引用儲存到靜態欄位s_theOneObject中。Singleton類沒有提供任何公用構造器,這防止了其他任何代碼構造類的其他執行個體。

在SingletonSerializationTest中,我們建立了包含兩個元素的一個數組;每個元素都引用Singleton對象。為了初始化兩個元素,我們調用Singleton的靜態GetSingleton方法。這個方法返回對一個Singleton對象的引用。對Console的WriteLine方法的第一個調用顯示true,證明兩個元素引用的是同一個對象。

現在SingletonSerializationTest調用格式化器的Serialize方法序列化數組及其元素。序列化第一個Singleton時,格式化器檢測Singleton類型實現了ISerializable介面,並調用GetObjectData方法。這個方法調用SetType,向它傳遞SingleSerializationHelper類型,告訴格式化器將Singleton對象序列化成一個SingleSerializationHelper對象。由於AddValue沒有調用,所以沒有額外的欄位資訊寫入流。由于格式化器自動檢測出兩個數組元素都引用一個對象,所以格式化器只能序列化一個對象。

 

序列化數組之後,SingletonSerializationTest調用格式化器的Deserialize方法。對流進行還原序列化時,格式化器嘗試還原序列化一個SingleSerializationHelper對象,這是格式化器之前被“欺騙”所序列化的東西。構造好SingleSerializationHelper對象夠,格式化器發現這個類型實現了IObjectReference介面,格式化器會調用GetRealObject方法。這個方法返回在對象還原序列化好之後你整整想要引用的對象。在我的例子中,SingleSerializationHelper類型讓GetRealObject返回對AppDomain中已存在的Singleton中已存在的Singleton對象的一個引用。所以,當格式化器的Deserialize方法返回時,a2數組包含兩個元素,兩者都引用Appdomin的Singleton對象。

第七節:將類型序列化為不同的類型以及將類型還原序列化為不同的對象

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.