《ASP.NET本質論》視圖狀態 ViewState

                序列化和反序列化
                   對象在內存中以引用的方式相互聯結,構成一個複雜的對象數。但是,在外部的設備中,卻是以一定的序列保存的,比如,圖片文件是以一個有規律的字節序列進行保存的,文本文件是通過字符序列進行保存。所以,內存中的對象如果需要保存到使用序列方式存儲的設備在,必須要進行信息的重組,以序列的方式進行描述,才能完成這個任務。這個工作就稱爲序列化。
                  反序列化就是從序列中重新構建內存中對象的過程。
                  例如,下面定義的是一個Person類。

 [Serializable]
    public class Person
    {
        public int Age { get; private set; }
        public string Name { get; private set; }
        public Person(string name, int age)
        {
            this.Name = name;
            this.Age = age;
        }
    }

當我們創建一個Person類哦對象實例alice之後,在內存中將會有如下的存儲結構:
Person alice = new Person("alice", 20);

對象在內存中的表示形式如圖所示:

             在C++中,程序員需要參與到序列化和反序列的過程中,在 .NET 中,通過反射,已經可以不再需要程序員參與,非常簡單地實現對象的序列化和反序列化。
             在System.Runtime.Serialization 命名空間中,定義了 .NET 中進行序列化和反序列所需要的類和接口。其中接口IFormatter定義了序列化器。
          
                       public interface IFormatter

            主要方法Serialize完成對象的序列化工作,將對象序列化之後寫入到流中。
              
               
public void Serialize (
	Stream serializationStream,
	Object graph
)

          Deserialize從流中獲取信息,還原爲內存中的對象。
               
public Object Deserialize (
	Stream serializationStream
)

           在.NET類庫中,命名空間 System.Runtime.Serialization.Formatters.Binary 提供了一個二進制的序列化器 Binary。
[ComVisibleAttribute(true)] 
public sealed class BinaryFormatter : IRemotingFormatter, IFormatter

        使用BinaryFormatter可以非常方便地將alice對象序列化爲一個字節序列。
        在序列化的方法中,需要提供一個字節流以保持序列化的結果。爲了方便,這裏使用MemoryStream將序列化的結果保存在內存中以便使用。
Person alice = new Person("alice", 20);

            BinaryFormatter formatter = new BinaryFormatter();
            System.IO.MemoryStream ms = new System.IO.MemoryStream();
            formatter.Serialize(ms, alice);

            byte[] content = ms.ToArray();
            Response.Write(BitConverter.ToString(content));

      我們可以將這些字節通過一個用於讀取字節流提供基於流的訪問,然後藉助於反序列化方法重新在內存中構建一個新的Person對象,這個對象顯然不是原來的Person對象,但是,表示的數據都是相同的,所以,從數據的角度來說,我們可以認爲還原了原來的對象。
            
System.IO.MemoryStream ms2 = new System.IO.MemoryStream(content);
            Person alice2 = formatter.Deserialize(ms2) as Person;
            
            Response.Write("<br/>"+alice2.Name+"<br/>"+alice2.Age);




         序列化控制
               剛纔我們將對象序列化爲二進制表示形式,這樣的序列化被稱爲二進制序列化。那麼,是不是任何對象都可以進行二進制序列化呢?如果不是的話,什麼樣的類可以被這樣進行二進制序列化呢?
              注意,上面定義的Person類,被標註了一個表情。
                           [Serializable]
             這個標籤的定義如下(在使用中,後綴Attribute可以省略)。

public abstract class Attribute : _Attribute
             在使用二進制序列化器的時候,當一個類應用了這個標籤,表示這個類的對象實例可以被序列化,如果沒有被標記爲可序列化,那麼,在使用BinaryFormatter進行序列化的時候,CLR將會拋出一個序列化的異常 SerializationException。
            這個標籤也可以被應用在類的成員上,不過,在默認情況下,類中的素有私有和共有的成員在序列化的過程中都將被序列化。也就是說,對於支持序列化的類來說,默認情況下,成員已經被應用了支持序列化的標籤。如果這個類標註這個標籤,可以定製這種類型的序列化過程。
public interface ISerializable
{
    void GetObjectData(
        SerializationInfo info,
        StreamingContext context
    );
}

           在.NET 中,所有的值類型都支持序列化。對於類來說,應用Serializable標籤的類將支持序列化操作。例如,常見的System.String,List<T> ,Dictionary<TKey,TValue>,ArrayList 等類型都支持序列化操作。
         
 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章