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]属性标记