深度复制(Deep copy):从一个变量到另一个变量按值复制对象,即产生一个和原对象相同的并且没有任何引用联系的对象。
浅度复制(Shallow copy):只复制对象的基本类型,而引用类型仍属于原来的对象。
浅度复制
可以使用Systrm.Object的MemberwiseClone()方法来完成,这是一个受保护的方法,但很容易再对象上定义一个调用该方法的公共方法,从而实现浅度复制。
class Program
{
static void Main(string[] args)
{
Person person=new Person(){id=1};
ShallowProto shallowProto=new ShallowProto(person,20);
ShallowProto shallow = (ShallowProto)shallowProto.clone();
Console.WriteLine("原型id:{0},原型age:{1}",shallowProto.person.id,shallowProto.age);//
Console.WriteLine("浅复制id:{0},浅复制age:{1}", shallow.person.id,shallow.age);
Console.WriteLine("给id和age赋新值后---------");
shallow.person.id = 2;
shallow.age = 30;
Console.WriteLine("原型id:{0},原型age:{1}", shallowProto.person.id, shallowProto.age);
Console.WriteLine("浅复制id:{0},浅复制age:{1}", shallow.person.id, shallow.age);
Console.ReadKey();
}
}
class ShallowProto:ICloneable
{
public Object clone()
{
return this.MemberwiseClone();
}
public int age;
public Person person;
public ShallowProto(Person person,int age)
{
this.person = person;
this.age = age;
}
}
class Person
{
protected int id;
}
运行结果:
可见浅复制后,值类型的成员与原型没有关系,而引用类型会变化。
浅度复制与两个对象指向同一个地址
浅度复制,与直接让两个引用的地址相同,浅复制会把值类型复制,引用类型只复制了地址。
class Program
{
static void Main(string[] args)
{
Person person=new Person(){id=1};
ShallowProto shallowProto=new ShallowProto(person,20);
ShallowProto shallowProto1 = shallowProto;
Console.WriteLine("原型id:{0},原型age:{1}", shallowProto.person.id, shallowProto.age);
Console.WriteLine("引用id:{0},引用age:{1}", shallowProto1.person.id, shallowProto1.age);
Console.WriteLine("给id和age赋新值后---------");
shallowProto1.age = 30;
shallowProto1.person.id = 2;
Console.WriteLine("原型id:{0},原型age:{1}", shallowProto.person.id, shallowProto.age);
Console.WriteLine("引用id:{0},引用age:{1}", shallowProto1.person.id, shallowProto1.age);
Console.ReadKey();
}
}
class ShallowProto
{
public ShallowProto clone()
{
return (ShallowProto)this.MemberwiseClone();
}
public int age;
public Person person;
public ShallowProto(Person person,int age)
{
this.person = person;
this.age = age;
}
}
class Person
{
public int id;
}
运行结果:
两个变量均引用同一个对象。
深度复制
标准的实现方式是:实现ICloneable接口,该接口有一个Clone()方法,这个方法不带参数,返回一个Object类型的结果。
class Program
{
static void Main(string[] args)
{
DeepProto deepProto=new DeepProto(2);
DeepProto deepClone = deepProto.Clone() as DeepProto;
Console.WriteLine("原型id:{0}", deepProto.person.id);
Console.WriteLine("深复制id:{0}", deepClone.person.id);
deepProto.person.id = 5;
Console.WriteLine("原型id:{0}", deepProto.person.id);
Console.WriteLine("深复制id:{0}", deepClone.person.id);
Console.ReadKey();
}
}
public class Person
{
public int id;
public Person(int id)
{
this.id = id;
}
}
class DeepProto:ICloneable
{
public Person person=new Person();
public DeepProto(int id)
{
person.id = id;
}
public Object Clone()
{
DeepProto cloneDeepProto=new DeepProto(person.id);
return cloneDeepProto;
}
}
运行结果: