Skip to main content

深拷贝与浅拷贝

在 C# 中,深拷贝(Deep Copy)和浅拷贝(Shallow Copy)是两种不同的对象复制方式。

核心区别在于对引用类型字段的处理方式以及复制后的对象独立性。

浅拷贝:适用于对象结构简单且引用类型字段无需独立修改的场景(如临时快照)。

深拷贝:适用于需要完全隔离的场景(如多线程操作、持久化备份)。


浅拷贝(Shallow Copy)

  • 定义:浅拷贝仅复制对象本身的值类型字段和引用类型字段的引用(即内存地址),而不复制引用类型字段指向的实际对象。
  • 特点

原始对象和副本共享引用类型字段的实际数据。

修改副本中的引用类型字段(如修改属性值)会影响原始对象,反之亦然。

  • 实现方式

​ 使用 MemberwiseClone() 方法(继承自 System.Object),这是 C# 默认提供的浅拷贝机制。

​ 直接赋值(如 var copy = original;)也是浅拷贝的一种形式。

  • 示例
public class Person { public string Name; }
var original = new Person { Name = "Alice" };
var shallowCopy = (Person)original.MemberwiseClone();
shallowCopy.Name = "Bob"; // 修改副本会影响原始对象
Console.WriteLine(original.Name); // 输出 "Bob"

深拷贝(Deep Copy)

  • 定义:深拷贝会递归复制对象及其所有引用类型字段指向的实际对象,生成一个完全独立的副本。

  • 特点

  • 原始对象和副本不共享任何引用类型字段的数据。

  • 修改副本不会影响原始对象,反之亦然。

  • 实现方式

  • 手动实现:为每个引用类型字段创建新实例并赋值(适用于简单对象)。

  • 序列化:通过二进制、JSON 或 XML 序列化与反序列化(需对象标记为 [Serializable])。

  • 反射:递归复制所有字段(包括私有字段)。

  • 第三方库:如 AutoMapperDeepCloner(高性能)。

  • 示例(使用 JSON 序列化)

using Newtonsoft.Json;
var original = new Person { Name = "Alice" };
var deepCopy = JsonConvert.DeserializeObject<Person>(JsonConvert.SerializeObject(original));
deepCopy.Name = "Bob"; // 不影响原始对象
Console.WriteLine(original.Name); // 输出 "Alice"

关键区别总结

对比项浅拷贝深拷贝
引用类型处理复制引用(共享数据)递归复制实际对象(独立数据)
性能高效(仅复制引用)较低(需递归或序列化)
适用场景临时副本、无需独立性的场景需完全隔离的场景(如缓存、线程安全)
实现复杂度简单(MemberwiseClone复杂(需手动或序列化)