[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();
}
}
序列化執行畫面如下:
接下來便是實作反序列化的部份,這次小的直接實作泛型反序列化,用戶端的程式碼如下:
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();
}
}
在資料繫結類別跟結構就一樣了。
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");
}
執行畫面如下:
後記:不過結構在處理資料異動的時候與類別似乎不太一樣,目前還是不知如何用結構繫結異動資料,將 [ADO.NET][Winform] DTO 與 DataGridView更新問題 裡的
public class Fields : INotifyPropertyChanged 改成 public struct Fields : INotifyPropertyChanged,會出現以下錯誤,不知在處理結構時還需要注意些什麼?
若有謬誤,煩請告知,新手發帖請多包涵
Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET