C#中的浅拷贝与深拷贝
浅拷贝与深拷贝的概念
浅拷贝(Shallow Copy)仅复制对象的顶层结构,若对象包含引用类型成员(如数组、类实例),则复制的是引用地址而非实际数据。拷贝后的对象与原对象共享引用成员。
深拷贝(Deep Copy)会递归复制对象的所有层级结构,包括引用类型成员的实际数据。拷贝后的对象与原对象完全独立,不共享任何引用。
实现方式
浅拷贝实现
在C#中,可通过MemberwiseClone
方法实现浅拷贝:
public class MyClass
{public int Value;public List<string> Names;public MyClass ShallowCopy(){return (MyClass)this.MemberwiseClone();}
}
深拷贝实现
需手动递归复制所有引用类型成员:
public class MyClass : ICloneable
{public int Value;public List<string> Names;public object Clone(){var copy = new MyClass();copy.Value = this.Value;copy.Names = new List<string>(this.Names); // 创建新列表return copy;}
}
或通过序列化实现通用深拷贝:(弃用,BinaryFormatter不安全)
using System.Runtime.Serialization.Formatters.Binary;public static T DeepCopy<T>(T obj)
{using (var ms = new MemoryStream()){var formatter = new BinaryFormatter();formatter.Serialize(ms, obj);ms.Position = 0;return (T)formatter.Deserialize(ms);}
}
通过json序列化,反序列化实现:
function deepCopy(obj) {return JSON.parse(JSON.stringify(obj));
}
Unity中的典型应用场景
浅拷贝适用场景
- 需要快速复制组件配置但允许共享部分引用数据时(如多个NPC共享同一行为树引用)。
- 复制Transform等轻量级Unity对象,其内部引用由引擎管理。
深拷贝适用场景
- 复制可序列化的ScriptableObject资产,避免修改原资产。
- 需要独立副本的游戏对象实例化(如预制体深层次状态复制)。
- 网络同步时传输完全独立的对象状态数据。
性能与注意事项
- 浅拷贝性能开销低,适合高频调用的简单对象复制。
- 深拷贝对复杂对象可能引发性能问题,需避免每帧调用。
- Unity中部分原生类型(如Texture、Material)需特殊处理,不能直接序列化深拷贝。
- 使用
[System.NonSerialized]
标记不需要深拷贝的字段。
示例:Unity中的深拷贝组件
using UnityEngine;
using System;[Serializable]
public class CharacterStats : ICloneable
{public float health;public float[] resistances; // 数组需深拷贝public object Clone(){var copy = new CharacterStats();copy.health = this.health;copy.resistances = (float[])this.resistances.Clone();return copy;}
}public class Enemy : MonoBehaviour
{public CharacterStats stats;public Enemy CreateClone(){var newEnemy = Instantiate(this);newEnemy.stats = (CharacterStats)stats.Clone();return newEnemy;}
}