在C++中,也可以创建引用,但是默认情况下所有的变量包括自定义类都是值类型,在声明一个变量的时候,空间就分配好了,构造函数就执行完了,这是自动类型的变量。但是在C#中,有引用类型的存在,在创建引用类型的变量的时候,变量是创建好了,但是它引用的内存空间并没有分配好(就像在C++中声明了指针类型的变量一样),所以需要使用new创建真正的实例,使用new创建出来的内存,像是C++中的智能指针,当没有变量指向它的时候就会被回收了,C#也没有delete关键字,所以不需要担心内存泄漏的问题。
自定义类都是引用类型,结构体都是值类型,其他的参见C#数据类型,引用类型就需要new。
using System; class Data { public int Number; } class MainClass { static void Main(string[] args) { Data d1 = new Data(); d1.Number = 1; Data d2 = d1; // d1 d2 是共享内存区的 d2.Number = 2; Console.WriteLine(d1.Number); // 被修改为了2 ChangeNumber(d1); Console.WriteLine(d1.Number); // 被修改为了3 } static void ChangeNumber(Data d) { d.Number += 1; // 在函数内的修改也是在真正的内存区上进行的 } }
思路1: 手动复制成员变量
思路2: 序列化为字节流后,再复制,当然这就要求支持序列化
需要自己手写实现。类型需要是可以支持序列化的。
using System.Runtime.Serialization.Formatters.Binary; using System.Collections; using System.Collections.Generic; using System.IO; using UnityEngine; public static class DataHelper { public static T DeepClone<T>(this T obj) { using (var ms = new MemoryStream()) { var formatter = new BinaryFormatter(); formatter.Serialize(ms, obj); ms.Position = 0; return (T)formatter.Deserialize(ms); } } }