一、赋值的操作
1、 例子1-1 引用类型赋值
可以看出赋值并不是深拷贝也不是浅拷贝,赋值只是给引用的对象重新起了个别名,一个改变另一个也会发生改变,因此这里的赋值操作其实复制的是引用,指向的是同一个实例的内存地址
值得注意的是该例子是引用类型的赋值操作。所以它引用的是同一个实例(这里涉及到值类型和引用类型的分配机制)例如: 值类型存储在栈上,引用类型分配在堆上
2、 例子1-2 值类型赋值
由例子代码可见值是分配在不同栈地址上,不同变量的地址也不同,因此这里的示例其实声明了两个不同的值类型变量,因此所指向的栈地址不同,Number 改变值的时候,其实只是改变Number这个值对象的栈地址
二、浅拷贝。值类型成员独立,但是引用类型成员共享。
1、由例子可看出car的值类型成员改变,carCp的值类型成员没有改变
2、由例子2-(2,3)观察car和carCp的引用类型成员都发生了改变,因此引用类型成员引用的其实是同一个地址
例子2-2
例子2-3
三、深拷贝:值类型成员和引用类型成员都是互相独立的,即创建了一个新的对象
例子3-1
例子3-2
从代码可看出,进行深拷贝实现后,类型成员和引用类型成员都是互相独立的,改变其对象值都互相不影响
四、示例代码
public class Car: ICloneable { public string Name { get; set; } public int type { get; set; } public object obj { get; set; } public Cat Cat { get; set; } /// <summary> /// 创建当前浅拷贝副本 /// </summary> /// <returns></returns> public object Clone() { return (Car)this.MemberwiseClone(); } /// <summary> /// 深拷贝 /// </summary> /// <param name="car"></param> /// <returns></returns> public object Clone(Car car) { //创建对象 Car NewCar = new Car(); NewCar.Name = car.Name; NewCar.type = car.type; NewCar.Cat = new Cat(car.Cat.Name); return NewCar; } }
以上如有不对,请大家纠正,感谢
本文参考和引用LoveMIss-Y 作者的博客,感谢
总结:
1、赋值。赋值和深度复制,浅度复制完全是不同的概念,并没有什么关系,很多文章说赋值对于值类型是深度复制,对于引用类型是浅度复制,这种说法是不正确的,它的本质是在线程栈上产生一样的副本。
2、浅度复制。值类型成员独立,但是引用类型成员共享。
3、深度复制。值类型成员和引用类型成员都是独立的,即完完全全的一个全新的副本,称之为深度复制。