在 C# 中创建对象的副本
请看一下下面的代码(摘自 C# 书籍):
public class MyClass
{
public int val;
}
public struct myStruct
{
public int val;
}
public class Program
{
private 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
完全不同的实体呢?
Please have a look at the code below (excerpt from a C# book):
public class MyClass
{
public int val;
}
public struct myStruct
{
public int val;
}
public class Program
{
private 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();
}
}
I understands it produces the output below:
objectA.val = 20
objectB.val = 20
structA.val = 30
structB.val = 40
The last two lines of the output I have no problem with, but the first two tell me that objectA
and objectB
are pointing to the same memory block (since in C#, objects are reference types).
The question is how do make objectB
, a copy of objectA
so that it points to a different area in memory. I understand that trying to assign their members may not work since those members may be references, too. So how do I go about making objectB
a completely different entity from objectA
?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
你可以这样做:
然后你可以做
N.B.
MemberwiseClone()
创建当前 System.Object 的浅表副本。You could do:
then you can do
N.B.
MemberwiseClone()
Creates a shallow copy of the current System.Object.没有内置的方法。您可以让 MyClass 实现 IClonable 接口(但它已被弃用),或者只编写您自己的 Copy/Clone 方法。无论哪种情况,您都必须编写一些代码。
对于大对象,您可以考虑序列化+反序列化(通过 MemoryStream),只是为了重用现有代码。
无论采用哪种方法,请仔细考虑“副本”的确切含义。它应该有多深,是否有需要排除的 Id 字段等。
There is no built-in way. You can have MyClass implement the
IClonable
interface (but it is sort of deprecated) or just write your own Copy/Clone method. In either case you will have to write some code.For big objects you could consider Serialization + Deserialization (through a MemoryStream), just to reuse existing code.
Whatever the method, think carefully about what "a copy" means exactly. How deep should it go, are there Id fields to be excepted etc.
最简单的方法是在 MyClass 类中编写复制构造函数。
像这样的事情:
第二个构造函数只接受他自己类型的参数(您要复制的类型)并创建一个分配有相同
输出值的新对象:
The easiest way to do this is writing a copy constructor in the MyClass class.
Something like this:
The second constructor simply accepts a parameter of his own type (the one you want to copy) and creates a new object assigned with the same value
output:
已经有一个关于此的问题,您也许可以阅读它
深度克隆对象
没有 Clone()例如,您可以使用 Java 中存在的方法,但您可以在类中包含复制构造函数,这是另一种好方法。
这是一个示例,在构建新对象时复制成员“Attr”。
There's already a question about this, you could perhaps read it
Deep cloning objects
There's no Clone() method as it exists in Java for example, but you could include a copy constructor in your clases, that's another good approach.
This would be an example, copying the member 'Attr' when building the new object.