基礎命名空間:序列化 System.Runtime.Serialization


    對象通常都有狀態(state),從一個對象中抽取這種狀態,不論是將它存儲於某地,還是通過網絡傳送,這種抽取動作稱為“將一個對象序列化”,而反向處理過程,從一個被序列化的狀態重建一個對象即為反序列化。

    序列化工作系由一個特定的格式化器(formatter)完成,每個格式化器都提供Serialize和Deserialize兩個方法。當格式化器將某個對象序列化后,所得好結果被放入一個流(Stream)中,(所謂的流是字節序列的一個抽象概念)因此可以包容任何序列化格式。一對象被存儲於一個流之中,對象的狀態好久可以被存儲於磁盤上(或者說被持久化(persistent))

    對於一個可被序列化的類型,只需要給他表上[Serializable]特性,也可以只賦給某個特定的字段

   NonSerialized 指明被標記的字段不可序列化

下面是自己練習的示例:

1.二進制序列化

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks;

namespace SerializableTest
{
    public class Program
    {
        static void Main(string[] args)
        {
            Goods good = new Goods();
            good.name = "蘋果";
            good.price = 10;
            good.type = "水果";

            string dir = System.AppDomain.CurrentDomain.BaseDirectory;
            
            //序列化
            IFormatter formatter = new BinaryFormatter();
            Stream stream = new FileStream(dir+"test.bin", FileMode.Create, FileAccess.Write);
            formatter.Serialize(stream, good);
            stream.Close();//必須關閉
            
            //反序列化
            IFormatter reformatter = new BinaryFormatter();
            Stream filestream = new FileStream(dir+"test.bin", FileMode.Open, FileAccess.Read);

            //返回Object類型,必須強制轉換
            Goods newgood = (Goods)reformatter.Deserialize(filestream);

            Console.WriteLine(newgood.name);
            Console.WriteLine(newgood.price);
            Console.WriteLine(newgood.type);
            Console.ReadLine();

        }
    }

    [Serializable]
    public class Goods
    {
        /// <summary>
        /// 名稱
        /// </summary>
        public string name { get; set; }

        /// <summary>
        /// 價格
        /// </summary>
        public double price { get; set; }

        /// <summary>
        /// 分類
        /// </summary>
        public string type { get; set; }
    }
}

   上例使用二進制格式化器BinaryFormatter:System.Runtime.Serialization.Formatters.Binary;

注:Iformatter接口序列化對象時,只需要提供了Stream流對象就行了。將對象序列化到文件流(FileStream)、內存流(MemoryStream)、網絡流(NetworkStream)都可以。

在測試 特新NonSerialized 時出現了點問題:“特性“NonSerialized”對此聲明類型無效。它只對“field”聲明有效

      由於C#3.0 的新特性get/set訪問器,在編譯的時候,編譯器會自動為你生成對應的私有變量,變量名自動生成。

因此考慮 直接顯示聲明私有屬性 private int number,並標注[NonSerialized]特性。

運行結果:

 

2.XML序列化

   XML序列化,對象被以XML格式保存,XML序列化常常用在Web服務項目里(最近的項目里看到有模塊用到,所以自己學習一下)

      System.Xml.Serialization命名空間:含有使用XML序列化所需要的類和功能

             XmlSerializer類,提供序列化Serialeze()和反序列話Deserialize()方法。

             XmlIgnore屬性,讓XmlSerializer類跳過不序列化的成員(XML序列化 Serializable和NoSerialized屬性將被忽略,而是使用XmlIgnore屬性,它的作用與NoSerialized類似)

            例如:

/// <summary>
/// 分類
/// </summary>
[XmlIgnore]
public string type { get; set; }

 Goods good = new Goods();
            good.name = "蘋果";
            good.price = 10;
            good.type = "水果";
            good.Number = 12;

            string dir = System.AppDomain.CurrentDomain.BaseDirectory;

            //序列化
            XmlSerializer formatter = new XmlSerializer(typeof(Goods));
            FileStream stream = new FileStream(dir + "test.bin", FileMode.Create, FileAccess.Write);
            formatter.Serialize(stream, good);
            stream.Close();//必須關閉

            //反序列化
            XmlSerializer reformatter = new XmlSerializer(typeof(Goods));
            FileStream filestream = new FileStream(dir + "test.bin", FileMode.Open, FileAccess.Read);

            //返回Object類型,必須強制轉換
            Goods newgood = (Goods)reformatter.Deserialize(filestream);

            Console.WriteLine("名稱:" + newgood.name);
            Console.WriteLine("價格:" + newgood.price);
            Console.WriteLine("種類:" + newgood.type);
            Console.WriteLine("數量:" + newgood.Number);
            Console.ReadLine();

持久化后的XML數據

<?xml version="1.0"?>
<Goods xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <name>蘋果</name>
  <price>10</price>
  <Number>12</Number>
</Goods>

可以發現加了[XmlIgnore]特性的type字段沒有被序列化

注:public int Number被序列化了,private int number 沒有被序列化,據說XML序列化 private類型字段不能被序列化,且元素的屬性必須為讀/寫屬性

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM