【发布时间】:2019-02-26 16:15:09
【问题描述】:
我在使用 ICloneable 类时遇到了克隆列表的问题:
class MetroBoards : ICloneable
{
public int Iteration;
public List<int[]> MetroPieces = new List<int[]>();
public List<char> MetroPiecesDefinition = new List<char>();
public object Clone()
{
return this.MemberwiseClone();
}
}
在尝试更新克隆中的列表时,这两种方式都是:
MetroBoards NewBoard = new MetroBoards();
NewBoard = (MetroBoards)ChosenBoard.Clone();
NewBoard.MetroPieces[MoveOne] = Coordinates;
这样:
MetroBoards (MetroBoards)ChosenBoard.Clone();
NewBoard.MetroPieces[MoveOne] = Coordinates;
其中 MoveOne 是整数,坐标是 int[]。 当我更新克隆中的列表时,它会同时更新克隆和基础。
据我所知,“MemberwiseClone”应该为我提供一个深层副本,它应该创建一个带有其属性副本的新对象,该副本不应与新对象关联。
编辑
感谢 cmets,我重新阅读了文档并将克隆过程修改为:
class MetroBoards : ICloneable
{
public int Iteration;
public List<int[]> MetroPieces = new List<int[]>();
public List<char> MetroPiecesDefinition = new List<char>();
public object Clone()
{
MetroBoards ThisBoard = (MetroBoards)this.MemberwiseClone();
ThisBoard.MetroPieces = new List<int[]>();
foreach (int[] Piece in this.MetroPieces)
{
int[] temp = new int[2];
temp[0] = Piece[0];
temp[1] = Piece[1];
ThisBoard.MetroPieces.Add(temp);
}
return ThisBoard;
}
}
感谢您让我理解我的错误。
【问题讨论】:
-
MemberwiseClone 只做浅拷贝。这边是documented
-
我完全错过了。那我修改一下。谢谢。
-
ICloneable 无法使用,它错过了被其 chinny-chin-chin 上的一根头发所弃用。最终它不能,COM 迭代器需要它。接口没有足够好的契约。摆脱它并向您的类添加一个 DeepCopy() 方法。如果您绝对需要一个接口,请声明您自己的接口,使用 DeepCopy 而不是 Clone,这样合同就明确了。