標籤:
項目中,經常會遇到要建立一個對象的副本作為臨時變數或其它用途,需要new一個新對象出來,
然後把來源物件的各個屬性賦值給這個新對象,這樣,及時改變了新對象的屬性,來源物件也不會發生改變,即深拷貝。
顯然,寫入程式碼地把對象的一個個屬性賦值給另外一個對象,不僅繁瑣,而且容易出錯,對象的類刪掉一個屬性,
則這個副本需“減掉”這個屬性。
以Employee類為例,下面的代碼實現了Employee的深拷貝與淺拷貝:
Employee類:
[Serializable] public class Employee:ICloneable { public string IDCode { get; set; } public int Age { get; set; } //注意Department類要貼上序列化的的標記[Serializable], //因為Employee要被序列化,其所有屬性都要可被序列化 public Department Department { get; set; } /// <summary> /// 深拷貝 /// </summary> /// <returns></returns> public Employee DeepClone() { using (Stream objectstream = new MemoryStream()) { IFormatter formatter = new BinaryFormatter(); formatter.Serialize(objectstream, this); objectstream.Seek(0, SeekOrigin.Begin); return formatter.Deserialize(objectstream) as Employee; } } /// <summary> /// 淺拷貝 /// </summary> /// <returns></returns> public Employee ShallowClone() { return Clone() as Employee; } /// <summary> /// 建立當前System.Object的淺表副本 /// </summary> /// <returns></returns> public object Clone() { return this.MemberwiseClone(); } }View Code
Department類:
[Serializable] public class Department { public string Name { get; set; } public override string ToString() { return this.Name; } }View Code
Main方法:
static void Main(string[] args) { Employee emp1 = new Employee { IDCode = "10086", Age = 23, Department = new Department { Name = "資訊化部" } }; //淺拷貝 //Employee emp2 = emp1.ShallowClone() as Employee; //深拷貝 Employee emp2=emp1.DeepClone() as Employee; //修改emp2,emp1的各個屬性不會被修改 emp2.IDCode = "10087"; emp2.Age = 24; emp2.Department.Name= "研發部"; //輸出驗證 Console.WriteLine("編號:{0},部門:{1},年齡:{2}",emp1.IDCode,emp1.Department,emp1.Age); Console.WriteLine("編號:{0},部門:{1},年齡:{2}", emp2.IDCode, emp2.Department, emp2.Age); Console.ReadKey(); }View Code
運行:
總結:emp2為emp1深拷貝的副本,修改emp2的屬性,emp1的屬性不會改變。
深拷貝與淺拷貝