我真的不知道这些东西是如何在内存/处理器中发生的。
我创建了一个名为Block
的类,其中包含位置。我还有一个List<Block>
来存储我的块。
首先,我在该列表中添加一个块:
blocks.Add(new Block());
然后,我想要克隆那个块,这样我的列表中有两个不同位置的独立块:
Block clonedBlock = blocks[0];
blocks.Add(clonedBlock);
但是当我改变新创建的块的位置时,我也改变了第一个块的位置。
为什么会这样做,有没有办法阻止它?
顺便说一句,我注意到Lists似乎有一些奇怪的行为。 例如,在这种情况下:
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
这让我觉得Lists只包含类似指针的东西,当我尝试“克隆”一个块时,我只复制指针,但它指向的位置保持不变。同样的问题:有什么方法可以阻止这种情况吗?
修改:解决方案:Object.MemberwiseClone()- Method
答案 0 :(得分:3)
你的猜测基本上是正确的。类是引用类型,所以你的行clonedBlock = blocks [0];将clonedBlock设置为与块[0]相同的地址。对一个进行的任何更改都将反映在另一个中。你最好创建一个新的Block实例并将其添加到列表中,除非你有什么理由要复制另一个块并只是改变它的位置。
实现这一目标的一种方法是实现深层复制(我认为这个术语 - 自从我在C ++中做了很多事以来已经过了几年)。创建一个新的Block实例,然后将值从原始值复制到新的。
您可以查看实现ICloneable,或者只是编写自己的复制方法(实际上,如果您实现ICloneable,您仍然在编写自己的复制方法 - 接口只是确保使用它的类实现Clone
方法。深或浅是由实施者决定的。)
另外,请查看Object.MemberwiseClone方法。 Object.MemberwiseClone
执行浅拷贝,但有一个示例在示例部分同时执行浅拷贝和深拷贝。