C#序列化與反序列化以及深拷貝淺拷貝
阿新 • • 發佈:2019-01-05
基於二進位制資料流的序列化和反序列化
/// <summary> /// 序列化 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="obj"></param> public static void Serialize<T>(T obj) { try { using(FileStream fs = new FileStream("Serialize.bin", FileMode.OpenOrCreate)) { BinaryFormatter bf = new BinaryFormatter(); bf.Serialize(fs, obj);//序列化 } } catch (Exception ex) {throw; } } /// <summary> /// /// </summary> /// <typeparam name="T"></typeparam> /// <returns></returns> public static T Deserialize<T>() { T res = default(T); try {using (FileStream fs=new FileStream("Serialize.bin",FileMode.Open)) { BinaryFormatter bf = new BinaryFormatter(); res = (T)bf.Deserialize(fs); } } catch (Exception) { throw; } return res; }
此時需要序列化的物件必須要宣告為可序列化,只需要在宣告類的同時採用關鍵字Serializable,如下:
[Serializable] public class Test { public string Name { get; set; } public int Age { get; set; } }
以上便可以完成序列化的反序列化的操作。
基於二進位制序列化的反序列化的拷貝,C#是基於面型物件的開發語言,自定義宣告的類都是採用引用傳遞的形式,有時候資料的修改對於這種引用傳遞來說並不是我們想要的結果,因此我們需要該物件的一份拷貝。
以下是基於記憶體序列化的一種方式:
public static T Copy<T>(T obj) { if (obj == null) { return default(T); } T res = default(T); using (MemoryStream ms = new MemoryStream()) { BinaryFormatter bf = new BinaryFormatter(); bf.Serialize(ms, obj);//序列化 ms.Seek(0, SeekOrigin.Begin); res = (T)bf.Deserialize(ms);//反序列化 } return res; }
這樣獲取到的拷貝物件跟原來的物件就不是指向同一個地址,這樣操作新的物件也不會影響原來的物件。
還有一種是實現ICloneable介面,在Clone方法中返回物件的一個淺拷貝MemberwiseClone。
public class CopyTest : ICloneable { public string Name { get; set; } public int Age { get; set; } public object Clone() { return this.MemberwiseClone();//獲取副本 } }
通過以下方式便可以獲得物件的一個拷貝物件:
CopyTest ct = new CopyTest() { Name = "Test", Age = 99 }; CopyTest ct01 = (CopyTest)ct.Clone();