在C#中,浅克隆(Shallow Copy)和深克隆(Deep Copy)都是对象复制的方式,但它们在处理对象的引用类型成员时有很大的区别。
浅克隆(Shallow Copy)
浅克隆创建一个新对象,这个新对象是原始对象的一个副本。但是,对于引用类型的成员变量,浅克隆只复制引用而不是复制引用所指向的实际对象。这意味着浅克隆后的新对象和原始对象的引用类型成员指向的是同一个对象。
public class Address
{
public string City { get; set; }
}
public class Person
{
public string Name { get; set; }
public Address Address { get; set; }
public Person ShallowCopy()
{
return (Person)this.MemberwiseClone();
}
}
ShallowCopy
方法使用MemberwiseClone
来创建浅克隆。如果你修改克隆对象的Address
属性,它也会影响到原始对象的Address
,因为它们都指向同一个Address
对象。
深克隆(Deep Copy)
深克隆不仅复制对象本身,还递归地复制对象中所有的引用对象。深克隆创建的副本是一个完全独立的对象,与原始对象没有任何共享的引用数据。
实现ICloneable接口来实现深克隆:
我们可以通过手动实现深克隆,将每一个引用类型成员都克隆一遍。
public class Address : ICloneable
{
public string City { get; set; }
// 实现深克隆
public object Clone()
{
return new Address { City = this.City };
}
}
public class Person : ICloneable
{
public string Name { get; set; }
public Address Address { get; set; }
// 实现深克隆
public object Clone()
{
Person clonedPerson = (Person)this.MemberwiseClone();
// 递归克隆引用类型成员
clonedPerson.Address = (Address)this.Address.Clone();
return clonedPerson;
}
}
public class Program
{
public static void Main()
{
Person person = new Person { Name = "John", Address = new Address { City = "New York" } };
Person deepClone = (Person)person.Clone();
// 修改深克隆的 Address.City 属性
deepClone.Address.City = "Los Angeles";
Console.WriteLine(person.Address.City); // 输出 "New York"
Console.WriteLine(deepClone.Address.City); // 输出 "Los Angeles"
}
}
使用ICloneable
接口时,为了实现深克隆,需要在Clone
方法中手动克隆所有引用类型的成员。