在编程中,浅拷贝和深拷贝是用于复制对象的两种不同方式,它们的主要区别在于复制对象时对对象内部成员的处理方式。今天我们对此进行讨论。
目录
1 浅拷贝
2 深拷贝
1 浅拷贝
浅拷贝创建一个新对象,新对象的属性值会复制原始对象的属性值。对于值类型的属性,会复制其实际的值;而对于引用类型的属性,只会复制引用,即新对象和原始对象的引用类型属性会指向同一个内存地址。这意味着,如果通过新对象修改引用类型属性的内容,原始对象中对应的属性内容也会被修改。
示例代码:
// 定义一个引用类型的类class Person{public string Name;public readonly Address Address;public Person(string name, Address address){Name = name;Address = address;}// 浅拷贝方法public Person ShallowCopy()=>(Person)MemberwiseClone();}// 定义另一个引用类型的类class Address{public string City;public Address(string city)=>City = city;}public static void Main(string[] args){Address address = new Address("JiangXi");Person originalPerson = new Person("Nicole Potter", address);// 进行浅拷贝Person shallowCopiedPerson = originalPerson.ShallowCopy();// 修改浅拷贝对象的值类型属性shallowCopiedPerson.Name = "Starry";// 修改浅拷贝对象的引用类型属性shallowCopiedPerson.Address.City = "AnYuan";Console.WriteLine($"Original Person: Name - {originalPerson.Name}, City - {originalPerson.Address.City}");Console.WriteLine($"Shallow Copied Person: Name - {shallowCopiedPerson.Name}, City - {shallowCopiedPerson.Address.City}");}
运行结果:
需要注意的是:虽然我们说引用类型只会复制引用,如果通过新对象修改引用类型属性的内容,原始对象中对应的属性内容也会被修改。但是string是特殊的引用类型,对于 string
来说,由于其不可变性,即使多个引用指向同一个 string
对象,当对其中一个引用进行 “修改” 操作时,实际上是创建了新的对象,不会影响其他引用所指向的原对象。(string
类型具有不可变性,意味着一旦一个 string
对象被创建,它的内容就不能被更改。当你对一个 string
变量执行修改操作时,实际上是创建了一个新的 string
对象,并让变量指向这个新对象,而原对象保持不变。)
(MemberwiseClone()
是 System.Object
类中的一个受保护的方法,由于所有类都直接或间接地继承自 System.Object
类,因此所有类都可以使用该方法。它的作用是创建当前对象的一个浅拷贝。)
2 深拷贝
深拷贝同样会创建一个新对象,新对象的属性值会复制原始对象的属性值。与浅拷贝不同的是,对于引用类型的属性,深拷贝会递归地复制引用类型对象本身(“递归地复制引用类型对象本身” 意味着,如果一个引用类型对象包含其他引用类型的属性,深拷贝会继续对这些嵌套的引用类型属性进行复制,直到所有引用类型属性都被复制为独立的对象。),而不是仅仅复制引用。这意味着新对象和原始对象的引用类型属性指向不同的内存地址,修改新对象的引用类型属性内容不会影响原始对象的对应属性内容。
代码示例:
// 定义一个引用类型的类class Person{public string Name;public readonly Address Address;public Person(string name, Address address){Name = name;Address = address;}// 深拷贝方法public Person DeepCopy()=>new Person(Name, new Address(Address.City));}// 定义另一个引用类型的类class Address{public string City;public Address(string city)=>City = city;}public static void Main(string[] args){Address address = new Address("JiangXi");Person originalPerson = new Person("Nicole Potter", address);// 进行深拷贝Person deepCopiedPerson = originalPerson.DeepCopy();// 修改浅拷贝对象的值类型属性deepCopiedPerson.Name = "Starry";// 修改浅拷贝对象的引用类型属性deepCopiedPerson.Address.City = "AnYuan";Console.WriteLine($"Original Person: Name - {originalPerson.Name}, City - {originalPerson.Address.City}");Console.WriteLine($"Shallow Copied Person: Name - {deepCopiedPerson.Name}, City - {deepCopiedPerson.Address.City}");}
运行结果: