C#學習之序列化

對象序列化是將對象(比如Person對象)轉換爲二進制數據(字節流)反序列化是將二進制數據還原爲對象。對象是稍縱即逝的,不僅程序重啓、操作系統重啓會造成對象的消失,就是退出函數範圍等都可能造成對象的消失,序列化/反序列化就是爲了保持對象的持久化。就像用DV錄像(序列化)和用播放器播放(反序列化)一樣。對象序列化,只能針對對象的字段進行序列化。以下爲序列化與反序列化兩個示例。

示例1:序列化

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;//需要引用的命名空間

namespace _05對象序列化
{
    class Program
    {
        //總結:
        //對象→byte[]序列化一個對象,但對象中可以包含多種內容,一個集合也可以
        //作用:1.直接存儲對象;2.在網絡中可以直接發送對象信息
        //序列化步驟:1.序列化對象:BinaryFormatter bf = new BinaryFormatter();
        //2.創建文件流: using (FileStream fs=new FileStream("", FileMode.Create))
        //{
            //調用Serialize方法進行序列化
            //bf.Serialize(fs, sly);
        //}
        //3.只序列化字段信息,方法不被序列化

        //反序列化步驟:1.創建二進制序列化器(格式化器):BinaryFormatter bf = new BinaryFormatter();
        //2.創建文件流: using (FileStream fs=new FileStream("", FileMode.Create))
        //{
            //調用Deserialize方法進行反序列化
            //bf.Deserialize(fs);
        //}

        //序列化注意問題:
        //1.要被序列化的對象的類型必須標記爲可序列化爲[Sreializable]
        //2.父類也要標記
        //3.類中字段或屬性的類型也必須爲可序列化的
        static void Main(string[] args)
        {
            Person sly = new Person();
            sly.Name = "麥兜兜";
            sly.Age = 16;
            sly.Email = "[email protected]";
            sly.MyCar = new Car("QQ");

            //現在要想存儲sly這個對象,只能是,將【"麥兜兜",16,"[email protected]"】,只能將這些數據存儲起來,
            //下次用這些數據的時候,必須重新創建一個對象,然後這個對象的屬性中的值,是來源於上個對象的。。

            //思考:能不能直接把sly這個對象存儲起來。這樣的話,下次使用的時候直接拿來就是一個對象,不需要重新創建。

            //對象序列化的步驟
            //1.創建二進制對象序列化器
            BinaryFormatter bf = new BinaryFormatter();
            //創建一個文件流
            using (FileStream fs = new FileStream("", FileMode.Create))
            {
                //2.開始執行序列化
                //將對象sly,序列化到fs文件流中,最終sly就保存到了根目錄(Debug)person.bin文件中。
                bf.Serialize(fs, sly);
            }
            Console.WriteLine("ok");
            Console.ReadKey();         
        }
    }
    //Person類型要想被序列化,
    //1.必須Person類型本身是可序列化的(即Person類型標記爲可序列化)
    //2.類中所有的字段屬性的類型也必須標記爲可序列化的
    //3.當前類型的所有父類也必須標記爲可序列化的
    [Serializable]
    public class Person : ShenWu
    {
        //4.建議,在使用序列化的時候儘量避免使用自動屬性,因爲自動屬性,每次編譯的時候自動生成的字段名可能不一樣,所以在反序列化的時候可能會造成問題。
        private string _name;
        public string Name
        {
            get
            {
                return _name;
            }
            set
            {
                _name = value;
            }
        }
        private int _age;
        public int Age
        {
            get
            {
                return _age;
            }
            set
            {
                _age = value;
            }
        }
        private string _email;
        public string Email
        {
            get
            {
                return _email;
            }
            set
            {
                _email = value;
            }
        }

        private Car _myCar;

        public Car MyCar
        {
            get { return _myCar; }
            set { _myCar = value; }
        }
    }

    [Serializable]
    public class ShenWu//Person繼承該類,所以也需要進行可序列化標記[Serializable]
    {
        public void Say()
        {
            Console.WriteLine("新陳代謝!");
        }
    }

    [Serializable]
    public class Car//Car作爲Person中的屬性字段,也需要進行可序列化標記[Serializable]
    {
        public Car(string brand)
        {
            this.Brand = brand;
        }
        private string _brand;
        public string Brand
        {
            get
            {
                return _brand;
            }
            set
            {
                _brand = value;
            }
        }
    }
}


示例2:反序列化
說明:非網絡流中需要添加序列化集引用,在本例中即添加“05對象序列化”

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using _05對象序列化;

namespace _06反序列化
{
    class Program
    {
        static void Main(string[] args)
        {
            //反序列化步驟:
            //1.創建二進制序列化器(格式化器)
            BinaryFormatter bf = new BinaryFormatter();

            using (FileStream fs = new FileStream("person.bin", FileMode.Open))
            {
                //2.開始執行反序列化
                //在執行反序列化的時候,由於person.bin中是存儲的是原來Person類型序列化後的結果,
                //所以要對person.bin反序列化時,需要Person類所在的程序集。

                //問題:爲什麼反序列化的時候需要原來定義Person類的那個程序集?
                //反序列話的時候,要返回一個對象,這個對象必須根據原來Person所在的程序集才能創建,
                //也就是說person.bin中包含的僅僅是一些數據,根據這些數據是無法在內存中創建對象的。
                //只能是根據原來Person類型的程序集來創建對象,然後把person.bin中的數據一一對應進行賦值。
                //object obj = bf.Deserialize(fs);
                //對象序列化,只是對對象的一些狀態信息進行序列化(比如:字段)。
                //對於方法之類的根本不進行序列化,也就是說person.bin中只包含字段名和字段值,根本沒有方法信息。
                //但是反序列化的時候,返回的是一個對象,那麼只根據這些字段信息是無法創建對象的,所以這個時候
                //需要先根據原來的程序集,獲取Person類型,然後在內存中創建一個Person對象,然後再把反序列化得到的字段信息賦值給這個Person對象。

                Person per = (Person)bf.Deserialize(fs);//此處“Person”即“05對象序列化”中定義的Person類
                Console.WriteLine("Name:{0},Age:{1},Car:{2}", per.Name, per.Age, per.MyCar.Brand);
            }
            Console.WriteLine("ok");
            Console.ReadKey();
        }
    }
}


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