深拷贝与浅拷贝

项目中,经常会遇到要创建一个对象的副本作为临时变量或其它用途,需要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的属性不会改变。

 

posted @ 2015-07-04 19:29  秋刀鱼No1  阅读(223)  评论(0编辑  收藏  举报