所谓浅拷贝就是复制值类型的字段,对该字段执行逐位复制。如果字段是引用类型的,则复制引用但不复制引用的对象。
C#中每个类都有一个MemberwiseClone()方法,可以实现对对象的浅拷贝。
先看个列子:
namespace DeepCopy
{
public class FullName
{
private string firstName;
private string lastName;
public string FirstName
{
get{ return firstName;}
set { firstName = value; }
}
public string LastName
{
get { return lastName; }
set { lastName = value; }
}
}
class Person : ICloneable
{
private FullName name;
private string sex;
private string age;
public Person()
{
name = new FullName();
}
public void SetPersonInfo(string firstName, string lastName, string sex, string age)
{
this.sex = sex;
this.age = age;
name.FirstName = firstName;
name.LastName = lastName;
}
public void Display()
{
Console.WriteLine("The person Information: {0}.{1}, {2}, {3}",name.FirstName,name.LastName,sex,age);
}
public object Clone()
{
return (object)this.MemberwiseClone();
}
}
}
客户端:
namespace DeepCopy
{
class Program
{
static void Main(string[] args)
{
Person p1 = new Person();
p1.SetPersonInfo("Vincent","Wu","Male","27");
Person p2 = (Person)p1.Clone();
p2.SetPersonInfo("Lucy", "Wu", "Female", "28");
p1.Display();
p2.Display();
Console.ReadKey();
}
}
}
输出的结果是:
The person Information: Lucy.Wu, Male, 27
The person Information: Lucy.Wu, Female, 28
为什么两次Display的结果一样? 前面说到了,字段是引用类型的只是复制其引用,不复制对象。所以我们p2中复制的只是p1的引用,并没有重新为它复制一个对象,那么p2改变name的时候,p1也跟着改变。
那么我们怎么修改呢?这个需要深度拷贝了。
见代码:
public object Clone()
{
Person obj = new Person();
obj.age = this.age;
obj.sex = this.sex;
return (object)obj;
}
就是把浅拷贝中的Clone()方法改一下。深度复制就是把引用对象的变量指向复制过的新对象,而不是原有的被引用的对象。
PS: 文中的代码在VS2008上编译没问题。有些观点是从《大话设计模式》中引用来, 详见第九章的原型模式。
如果有错误或者不准确的地方还请网友指出。在此谢过。