回顾002--C# 中 赋值 VS浅拷贝 VS 深拷贝

 

 一:通俗解释:
赋值:---如果是值类型或者string,赋值的实例;如果是引用类型,赋值的是引用地址

浅拷贝----仅仅复制了引用地址,复制对象或被复制对象的改变,是互相影响的(一变则都变)
深拷贝---对对象的完全复制,即:复制对象或被复制对象的改变,相互不影响(相互独立,互不影响)

 

二:实例说明:

值类型的复制都是深拷贝;

引用类型的复制(没有特殊处理过)都是浅复制(string类型)

 

对于类型来说存在这样一个有趣现象:(代码见附件:Employee类中有属性:Department(Department类型)Emp_Name(string类型),Emp_Age(int类型))
假设:存在
Employee对象emp;

创建新对象

Employee empCopy= emp;

Employee empShalllowCopy=
emp.ShallowClone() as Employee;

Employee empDeepCopy=
emp.DeepClone() as Employee;

结果描述

emp的属性变化时,empCopy对象的属性跟着变化

解析:直接赋值,则
empCopy得到的是emp的应用地址,那么emp变化,empCopy会完全跟着变化


====》复制

emp属性变化时,empShalllowCopy对象中只有Department属性跟随emp的变化而变化

解析:
ShallowClone()内部调用了Clone()方法,通过此方法获得的对象实例,其值类型以及string与复制对象完全独立,但是对Department这个引用类型却只是复制了其引用地址,所以会被影响。
====》浅拷贝

emp属性变化时,empDeepCopy对象中的属性不变化。二者的变化不会相互影响。






====》深拷贝:二者已经完全独立了

 

 主要代码展示:

 
 Console.WriteLine("==============using self-define method: DeepClone &&  ShalllowClone");
            Employee emp1 = new Employee() { EmpName = "tom1", Age = 26, Department = new Department() { Dep_Id = 1, Dep_Name = "开发部门" } };
            Console.WriteLine("==============start Copy");// 完全相互影响
            Employee emp1CopyClone = emp1;
            emp1.EmpName = "jerryCopy";
            emp1.Age = 18;
            emp1.Department.Dep_Name = "测试部门Copy";
            Console.WriteLine(emp1CopyClone.EmpName + " " + emp1CopyClone.Age + " " + emp1CopyClone.Department.Dep_Name);

            Console.WriteLine("==============start  ShalllowClone");  //部分相互影响
            Employee emp1ShalllowClone = emp1.ShalllowClone();
            emp1.EmpName = "jerry1";
            emp1.Age = 28;
            emp1.Department.Dep_Name = "测试部门";
            Console.WriteLine(emp1ShalllowClone.EmpName + " " + emp1ShalllowClone.Age + " " + emp1ShalllowClone.Department.Dep_Name);

            Console.WriteLine("==============start  DeepClone");  //完全独立
            Employee emp1ShalllowClone1 = emp1.DeepClone();
            emp1.EmpName = "jerry1111";
            emp1.Age = 2811;
            emp1.Department.Dep_Name = "测试部门111";
            Console.WriteLine(emp1ShalllowClone1.EmpName + " " + emp1ShalllowClone1.Age + " " + emp1ShalllowClone1.Department.Dep_Name);

 类被克隆(深拷贝、浅拷贝),微软都建议类需继承ICloneable接口,用以明确告诉调用者该类可被拷贝:

[Serializable]
    public class Employee : ICloneable
    {
        public string EmpName { get; set; }
        public int Age { get; set; }
        public Department Department { get; set; }


        #region 默认实现接口 , 返回值类型为浅拷贝对象(仅对引用类型来说)----
        public object Clone()
        {
            return this.MemberwiseClone();
        }
        #endregion

        #region 自定义 深拷贝 和  浅拷贝 方法
        //浅拷贝
        public Employee ShalllowClone()
        {
            return Clone() as Employee;
        }
        //深拷贝
        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;
            }
        }
        #endregion

    }

 

 

 

 

posted @ 2013-06-16 22:23  daxiaxj  阅读(585)  评论(0编辑  收藏  举报