深拷贝与浅拷贝
项目中,经常会遇到要创建一个对象的副本作为临时变量或其它用途,需要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(); } }
Department类:
[Serializable] public class Department { public string Name { get; set; } public override string ToString() { return this.Name; } }
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(); }
运行截图:
总结:emp2为emp1深拷贝的副本,修改emp2的属性,emp1的属性不会改变。