如何在C#中不通过序列化实现真正的深拷贝?相关疑问解析
问题解答
1. 是否需要为每个类都创建UCopy类?它是仅用于拷贝单个类还是应设计为泛型?
不需要给每个类单独写一个UCopy类。书中的UCopy是针对自身类实现的拷贝逻辑,只是个示范案例。如果要复用拷贝逻辑,更合理的方式是:
- 让需要支持拷贝的类实现
ICloneable接口(注意接口本身不明确深/浅拷贝,必须在注释或文档里说明); - 或者编写泛型工具类,统一处理不同类型的拷贝逻辑。不过手动实现泛型深拷贝要处理递归遍历引用类型成员的问题,这也是为什么很多人选择序列化方式的原因——序列化可以自动处理嵌套引用的拷贝。
2. 该实现是否能创建真正的深拷贝?我认为u4并非真正的深拷贝,因为尽管AnotherClass对象是独立的,但Own值源于同一个static id,并非完全独立;
从对象实例的内存独立性来说,这个实现是真正的深拷贝。深拷贝的核心标准是:拷贝后的对象与原对象的所有引用类型成员都指向独立的内存实例,修改拷贝对象的引用成员不会影响原对象。这里u4.address是全新的AnotherClass实例,和u1.address完全是两个不同的对象,满足深拷贝的核心要求。
你提到的static id属于类级别的共享状态,不属于单个对象的实例数据。深拷贝只负责复制对象的实例成员,不会也不应该复制static成员——毕竟static变量是所有类实例共享的,不管创建多少个对象,都会共用同一个static值。这不是深拷贝的缺陷,是static成员本身的特性决定的。
3. Clone方法在此处的作用是什么?
代码里实际用到的是MemberwiseClone()(你说的Clone应该指这个),它是Object类的protected方法,作用是创建当前对象的浅拷贝:
- 它会生成一个新对象,然后把原对象的所有值类型成员逐位复制;
- 对于引用类型成员,只会复制引用(也就是新对象的引用成员和原对象指向同一个内存实例)。
在示例中的作用:
ShallowCopy()直接返回MemberwiseClone()的结果,所以新UCopy对象的address和原对象指向同一个AnotherClass实例,这就是浅拷贝;DeepCopy()先通过MemberwiseClone()得到浅拷贝的UCopy对象,再手动将address重新实例化一个新的AnotherClass,把浅拷贝升级成了深拷贝——因为引用类型成员也被替换成了独立的新实例。
书中代码示例(图3.5)
public class AnotherClass { private static uint id = 1000; private readonly uint own; public AnotherClass() { own = id++; } public uint Own => own; } public class UCopy { private AnotherClass address; public UCopy() { address = new AnotherClass(); } // Deep copy: heap memory allocated for a true copy public UCopy DeepCopy() { // Internal cast UCopy local = (UCopy)this.MemberwiseClone(); local.address = new AnotherClass(); return local; } // Shallow copy: distinct objects have the same address public UCopy ShallowCopy() { return (UCopy)this.MemberwiseClone(); } } public class Program { public static void Main() { // Client code // #1: UCopy object allocated UCopy u1 = new UCopy(); // Embedded 'Own' id of 1000 // #2: Shallow copy, aliased with u1 UCopy u2 = u1.ShallowCopy(); // Embedded 'Own' id of 1000 // #3: Shallow copy, aliased with u1 UCopy u3 = u1.DeepCopy(); // Embedded 'Own' id of 1000 // #4: Deep copy - DISTINCT object UCopy u4 = u1.DeepCopy(); // Embedded 'Own' id of 1001 } }
内容的提问来源于stack exchange,提问作者i_hate_F_sharp
相关产品推荐
相关产品推荐

