4

我真的不知道这些东西是如何在内部存储器/处理器中发生的。

我创建了一个名为Blockposition类。我也有一个List<Block>存储我的块。

首先,我在该列表中添加一个 Block:

blocks.Add(new Block());

然后,我想克隆该块,以便在我的列表中有两个具有不同位置的独立块:

Block clonedBlock = blocks[0];
blocks.Add(clonedBlock);

但是当我改变新创建的块的位置时,我也改变了第一个块的位置。

为什么会这样做,有什么办法可以防止这种情况发生吗?

顺便说一句,我注意到列表似乎有一些奇怪的行为。例如在这种情况下:

List<Block> list01 = new List<Block>();
[... add some blocks to that list ...]
List<Block> list02 = list01; // also tried: List<Block> list02 = list01.ToList();
[... change item in list01 ...] --> also changes that item in list02

这让我猜测列表只包含指针之类的东西,当我尝试“克隆”一个块时,我只复制指针,但它指向的位置保持不变。同样的问题:有什么办法可以防止这种情况发生吗?

编辑:解决方案:Object.MemberwiseClone()- 方法

4

1 回答 1

3

你的猜测基本上是正确的。类是引用类型,因此您的行 Block clonedBlock = blocks[0]; 正在将 clonedBlock 设置为与 blocks[0] 相同的地址。对其中一个所做的任何更改都将反映在另一个中。您最好创建一个 Block 的新实例并将其添加到列表中,除非出于某种原因您想要复制另一个块并简单地更改它的位置。

处理这个问题的一种方法是实现一个深拷贝(我认为这是一个术语——自从我在 C++ 中做任何事情以来已经有好几年了)。创建一个新的 Block 实例,然后将值从原始实例复制到新实例。

您可以查看实现 ICloneable,或者简单地编写自己的复制方法(实际上,如果您实现 ICloneable,您仍然在编写自己的复制方法 - 接口只是确保使用它的类实现Clone方法。深或浅取决于实施者)。

另外,请查看Object.MemberwiseClone方法。 Object.MemberwiseClone进行浅拷贝,但在示例部分中有一个同时进行浅拷贝和深拷贝的示例。

于 2013-06-01T02:39:46.187 回答