C#中有两种类型变量,一种 是值类型变量,一种是引用类型变量。对于前者,复制是属于全盘复制;而对后者,一般的复制只是浅表复制,相当于只复制了在内存的地址。
浅表与深表复制区别
是否对实例对象中对应的对象类型进行内存复制
浅表与深表复制举例
由例子可见,实例2虽然对实例1进行了复制,但是实例2的ColorQian 的赋值 仍然对实例1造成了影响
public class ColorQian
{
public int red;
public int green;
public int blue;
public ColorQian(int red, int green, int blue)
{
this.red = red;
this.green = green;
this.blue = blue;
}
}
public class MyobjectQian : ICloneable
{
public int id;
public string size;
public ColorQian color;
public MyobjectQian(int id, string size, ColorQian colorQian)
{
this.id = id;
this.size = size;
this.color = colorQian;
}
public object Clone()
{
return new MyobjectQian(this.id,this.size,this.color);
}
//重写Tostring方法
public override string ToString()
{
var s = String.Format("id:{0},size:{1},color:({2},{3},{4})",
this.id, this.size, this.color.red, this.color.green, this.color.blue);
return s;
}
}
public void QianTest()
{
ColorQian colorQian = new ColorQian(25, 99, 80);
MyobjectQian myobjectQian = new MyobjectQian(1001, "small", colorQian);
MyobjectQian myobjectQian1 = (MyobjectQian)myobjectQian.Clone();
myobjectQian1.size = "big";
myobjectQian1.id = 8001;
//ColorQian 浅表复制,只复制了地址
myobjectQian1.color.red =111 ;
myobjectQian1.color.blue = 111;
myobjectQian1.color.green = 111;
MyobjectQian myobject3 = (MyobjectQian)myobjectQian.Clone();
myobject3.size = "narmal";
myobject3.id = 9001;
//深表复制:进行对象复制的时候,对象所有成员都重写分配空间
myobject3.color = new ColorQian(100, 25, 89);
Console.WriteLine(myobjectQian);
Console.WriteLine(myobjectQian1);
Console.WriteLine(myobject3);
}
最直接的方法就是对每个类实现ICloneable接口的实现,从而实现深表复制,节约对象创建的时间
public class Color:ICloneable
{
public int red;
public int green;
public int blue;
public Color(int red, int green, int blue)
{
this.red = red;
this.green = green;
this.blue = blue;
}
//节约对象创建的时间
public object Clone()
{
return new Color(red , green, blue);
}
}
public class Myobject : ICloneable
{
public int id;
public string size;
public Color color;
public Myobject(int id, string size, Color color)
{
this.id = id;
this.size = size;
this.color = color;
}
Color的浅表复制
// public object Clone()
// {
// return new Myobject(this.id, this.size, this.color);
// }
//Color的深表复制
public object Clone()
{
return new Myobject(this.id, this.size, (Color)this.color.Clone());
}
//重写Tostring方法
public override string ToString()
{
var s = String.Format("id:{0},size:{1},color:({2},{3},{4})",
this.id, this.size, this.color.red, this.color.green, this.color.blue);
return s;
}
}
public void test1()
{
Color color = new Color(25, 99, 80);
Myobject myobject1 = new Myobject(1001, "small", color);
//调用clone创建新的Myobject
//在Clone时,出现对象引用的复制,为浅表复制,即只复制了该对象的地址,并没有重新分配地址
Myobject myobject2 = (Myobject)myobject1.Clone();
myobject2.size = "big";
myobject2.id = 5001;
//浅表复制
myobject2.color.red = 165;
myobject2.color.green = 56;
myobject2.color.blue = 45;
//深表复制:进行对象复制的时候,对象所有成员都重写分配空间
Myobject myobject3 = (Myobject)myobject1.Clone();
myobject3.size = "narmal";
myobject3.id = 9001;
myobject3.color = new Color(100, 25, 89);
Console.WriteLine(myobject1);//Console打印对象的时候默认调用Tostring方法
Console.WriteLine(myobject2);
Console.WriteLine(myobject3);
}