C#深拷贝的实现方式

C#中的引用类型,本质是记录一个指针,而直接的赋值被称为浅拷贝,只传递这个指针,指向的数据还是同一个。很多情况下,我们都希望这个数据赋值出来会是一个全新的东西,不会因旧数据的改变而改变,而这便是深拷贝

函数

记录一种深拷贝的方式:

public static T Clone<T>(T RealObject)
{
    using (Stream objectStream = new MemoryStream())
    {
        //利用 System.Runtime.Serialization序列化与反序列化完成引用对象的复制  
        IFormatter formatter = new BinaryFormatter();
        formatter.Serialize(objectStream, RealObject);
        objectStream.Seek(0, SeekOrigin.Begin);
        return (T)formatter.Deserialize(objectStream);
    }
}

示例

[Serializable]      // 需要深拷贝的类一定要加[Serializable]属性标记
public class AAA
{
    public string str;
    public AAA(string str)
    {
        this.str = str;
    }
}

public class NewBehaviourScript : MonoBehaviour
{
    private void Awake()
    {
        AAA a1 = new AAA("我是AAA对象的str值");     //创建对象
        AAA a2 = a1;    //浅拷贝
        AAA a3 = Clone<AAA>(a1);    //深拷贝

        print("----------------- 未修改的值 -------------------");
        print(string.Format("{0} - str:{1}", "[原始]a1", a1.str));
        print(string.Format("{0} - str:{1}", "[浅拷贝]a2", a2.str));
        print(string.Format("{0} - str:{1}", "[深拷贝]a3", a3.str));

        a1.str += "-- 修改后";
        print("----------------- 修改后的值 -------------------");
        print(string.Format("{0} - str:{1}", "[原始]a1", a1.str));
        print(string.Format("{0} - str:{1}", "[浅拷贝]a2", a2.str));
        print(string.Format("{0} - str:{1}", "[深拷贝]a3", a3.str));

    }

    public static T Clone<T>(T RealObject)
    {
        using (Stream objectStream = new MemoryStream())
        {
            //利用 System.Runtime.Serialization序列化与反序列化完成引用对象的复制  
            IFormatter formatter = new BinaryFormatter();
            formatter.Serialize(objectStream, RealObject);
            objectStream.Seek(0, SeekOrigin.Begin);
            return (T)formatter.Deserialize(objectStream);
        }
    }
} 

Tip

  • 需要深拷贝的类一定要加[Serializable]属性标记