可能重复:如何在.Net(特别是C#)中深层复制对象?
请看下面的代码(摘自C#书):
namespace Example {
class MyClass {
public int val;
}
struct myStruct {
public int val;
}
class Program {
static void Main(string[] args) {
MyClass objectA = new MyClass();
MyClass objectB = objectA;
objectA.val = 10;
objectB.val = 20;
myStruct structA = new myStruct();
myStruct structB = structA;
structA.val = 30;
structB.val = 40;
Console.WriteLine("objectA.val = {0}", objectA.val);
Console.WriteLine("objectB.val = {0}", objectB.val);
Console.WriteLine("structA.val = {0}", structA.val);
Console.WriteLine("structB.val = {0}", structB.val);
Console.ReadKey();
}
}
}
我知道它会产生下面的输出
objectA.val = 20
objectB.val = 20
structA.val = 30
structB.val = 40
输出的最后两行我没有问题,但前两行告诉我 objectA
和 objectB
指向同一个内存块(因为在C#中,对象是引用类型) .
问题是如何使 objectB
, objectA
的副本,以便它指向内存中的不同区域 . 我理解,尝试分配他们的成员可能不起作用,因为这些成员也可能是参考 . 那么如何让 objectB
与 objectA
完全不同呢?
谢谢
4 回答
没有内置方式 . 你可以让MyClass实现
IClonable
接口(但它有点被弃用)或只是编写你自己的Copy / Clone方法 . 在任何一种情况下,您都必须编写一些代码 .对于大对象,您可以考虑序列化反序列化(通过MemoryStream),只是为了重用现有代码 .
无论采用何种方法,都要仔细考虑“副本”的含义 . 它应该有多深,是否有被禁止的Id字段等 .
你可以这样做:
那么你可以做到
注:
MemberwiseClone()
创建当前System.Object的浅表副本 .最简单的方法是在MyClass类中编写一个复制构造函数 .
像这样的东西:
第二个构造函数只接受他自己类型的参数(您要复制的参数)并创建一个分配了相同值的新对象
输出:
关于这个问题已经有了问题,你也许可以阅读它
Deep cloning objects
例如,Java中不存在Clone()方法,但您可以在clases中包含复制构造函数,这是另一种好方法 .
这是一个例子,在构建新对象时复制成员'Attr' .