先上代码,后解释:
public class Person { public int Age; public DateTime BirthDate; public string Name; public IdInfo IdInfo; /// <summary> /// 浅拷贝(在当前对象中:只对值类型进行拷贝,并在堆中创建新的对象。) /// </summary> /// <returns></returns> public Person ShallCopy() { return (Person)this.MemberwiseClone(); } /// <summary> /// 深拷贝(在当前对象中:分别对值类型和引用类型进行拷贝,并在堆中创建新的对象。) /// </summary> /// <returns></returns> public Person DeepCopy() { Person other = (Person)this.MemberwiseClone(); other.IdInfo = new IdInfo(IdInfo.IdNumber); other.Name = String.Copy(Name); return other; } }
public class IdInfo { public int IdNumber; public IdInfo(int idNumber) { this.IdNumber = idNumber; } }
class Program { static void Main(string[] args) { Person p1 = new Person(); p1.Age = 42; p1.BirthDate = Convert.ToDateTime("1977-01-01"); p1.Name = "Jack Daniels"; p1.IdInfo = new IdInfo(666); // Perform a shallow copy of p1 and assign it to p2. Person p2 = p1.ShallCopy(); // Make a deep copy of p1 and assign it to p3. Person p3 = p1.DeepCopy(); // Display values of p1, p2 and p3. Console.WriteLine("Original values of p1, p2, p3:"); Console.WriteLine("p1 instance values: "); DisplayValues(p1); Console.WriteLine("p2 instance values:"); DisplayValues(p2); Console.WriteLine("p3 instance values:"); DisplayValues(p3); { // Change the value of p1 properties and display the values of p1, // p2 and p3. p1.Age = 32; p1.BirthDate = Convert.ToDateTime("1900-01-01"); p1.Name = "Frank"; p1.IdInfo.IdNumber = 7878; Console.WriteLine("\nValues of p1, p2 and p3 after changes to p1:"); Console.WriteLine("p1 instance values: "); DisplayValues(p1); Console.WriteLine("p2 instance values (reference values have changed):"); DisplayValues(p2); Console.WriteLine("p3 instance values (everything was kept the same):"); DisplayValues(p3); } Console.Read(); } public static void DisplayValues(Person p) { Console.WriteLine("" + $"Id: {p.IdInfo.IdNumber}\n" + $"Name: {p.Name}\n" + $"Age: {p.Age}\n" + $"BirthDate: {p.BirthDate}\n"); } }
设计图
浅拷贝:是把p1里面的属性值全部进行拷贝,并在堆中创建一个新的对象p3,现在p1和p3没有关系,p1改变并不会影响p3,p3的改变也不会影响p1,两者互不影响。
深拷贝:是把p1里面的值类i型属性值进行拷贝,并在堆中创建一个新的对象p2,现在p1和p2中的引用类型存在关系,p1中的引用类型改变则会影响p2中的引用类型,p2中的引用类型改变也会影响p1,两者互相影响。
注意事项:这里的string是一个比较特殊的类型