浅拷贝与深拷贝的概念

浅拷贝(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;
    }
}

更多推荐