[C#.NET] 結構 二進位序列化 / 反序列化

  • 8084
  • 0
  • 2012-01-09

[C#.NET] 結構 二進位序列化 / 反序列化

類別(class)與結構(struct),同樣都能進行序列化與資料繫結,它們倆很像但是還是有很大的差異,請查閱MSDN:結構和類別

namespace System.Member
{
    [Serializable]
    public struct MemberList
    {
        private BindingList<Member> _MemberCollection;
        public BindingList<Member> MemberCollection
        {
            get
            {
                if (this._MemberCollection == null)
                    this._MemberCollection = new BindingList<Member>();
                return this._MemberCollection;
            }
        }
    }
    [Serializable]
    public struct Member
    {
        public int? ID { get; set; }
        public string Name { get; set; }
        public int? Age { get; set; }
        public string Phone { get; set; }
    }
}

 

 

我先建立了兩個結構(struct),Member 與 MemberList,

PS.在實作的過程中發現,二進位序列化跟xml序列化不太一樣的地方是,二進位序列化在類別或結構上必須要加上[Serializable] attribute,而xml序列化倒是不用加。[ADO.NET] 類別(Data Transfer Object )與資料繫結


然後在用戶端建立以下

private void button1_Click(object sender, EventArgs e)
{
    MemberList list = CreateClass();
    SerializeToBinary("list.bin", list);
}


public MemberList CreateClass()
{
    MemberList list = new MemberList();
    list.MemberCollection.Add(new Member() { ID = 1, Name = "余小章", Age = 18, Phone = "000" });
    list.MemberCollection.Add(new Member() { ID = 2, Name = "王小華", Age = 28, Phone = "001" });
    list.MemberCollection.Add(new Member() { ID = 3, Name = "張小明", Age = 20, Phone = "002" });
    return list;
}


public static void SerializeToBinary(string FileName, object Object)
{
    Stream stream = null;
    IFormatter formatter = new BinaryFormatter();
    try
    {
        stream = new FileStream(FileName, FileMode.Create, FileAccess.Write, FileShare.Read);
        formatter.Serialize(stream, Object);
    }
    catch (Exception ex)
    {
        throw ex;
    }
    finally
    {
        stream.Close();
    }
}

 

序列化執行畫面如下:

image

 

接下來便是實作反序列化的部份,這次小的直接實作泛型反序列化,用戶端的程式碼如下:

private void button2_Click(object sender, EventArgs e)
{
    MemberList list = DeserializeFromBinary<MemberList>("list.bin");
}


public static T DeserializeFromBinary<T>(string FileName)
{
    IFormatter formter = new BinaryFormatter();
    Stream stream = null;

    try
    {
        stream = new FileStream(FileName, FileMode.Open, FileAccess.Read, FileShare.Read);
        object obj = formter.Deserialize(stream);
        if (obj == null)
            return default(T);
        else
            return (T)obj;
    }
    catch (Exception ex)
    {
        throw ex;
    }
    finally
    {
        stream.Close();
    }
}

 

反序列化執行畫面如下:
image

 


在資料繫結類別跟結構就一樣了。

BindingSource _Source = new BindingSource();
public void Form1_Load(object sender, EventArgs e)
{
    this._Source.DataSource = CreateClass().MemberCollection;

    this.dataGridView1.DataSource = this._Source;
    this.bindingNavigator1.BindingSource = this._Source;
    this.textBox1.DataBindings.Add("Text", this._Source, "ID");
    this.textBox2.DataBindings.Add("Text", this._Source, "Name");
    this.textBox3.DataBindings.Add("Text", this._Source, "Age");
    this.textBox4.DataBindings.Add("Text", this._Source, "Phone");
}

 

執行畫面如下:

image

 


後記:不過結構在處理資料異動的時候與類別似乎不太一樣,目前還是不知如何用結構繫結異動資料,將 [ADO.NET][Winform] DTO 與 DataGridView更新問題 裡的

public class Fields : INotifyPropertyChanged 改成 public struct Fields : INotifyPropertyChanged,會出現以下錯誤,不知在處理結構時還需要注意些什麼?

image

若有謬誤,煩請告知,新手發帖請多包涵


Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET

Image result for microsoft+mvp+logo