我使用此方法获得Tile
课程:
public object Clone()
{
return MemberwiseClone();
}
另一个继承自Checker
。
Tile
我还有一个Board
类List<Tile>
。我想克隆电路板,所以我写了这个:
public Board Clone()
{
var b = new Board(width, height);
foreach (var t in this) b.Add(t.Clone());
return b;
}
但它引发了一个错误:
无法从'object'转换为'Checkers.Tile'
现在我可以让Tile.Clone
方法改为Tile
,但MemberwiseClone
还会复制子Checker
中的其他属性吗?
如果这不是问题,那么上述Board.Clone
方法与此之间的语义差异是什么?
public Board Clone()
{
using (var ms = new MemoryStream())
{
var bf = new BinaryFormatter();
bf.Serialize(ms, this);
ms.Position = 0;
return (Board)bf.Deserialize(ms);
}
}
因为它们对我的程序肯定会产生不同的影响,即使我在打印电路板时看起来也是如此。我不认为某些东西是克隆但是正在返回引用。 Board
ctor看起来像这样:
public Board(int width = 8, int height = 8)
{
this.width = width;
this.height = height;
this.rowWidth = width / 2;
this.Capacity = rowWidth * height;
}
Tile
类实际上没有任何属性。检查器只有两个枚举属性:
public enum Color { Black, White };
public enum Class { Man, King };
public class Checker : Tile
{
public Color Color { get; set; }
public Class Class { get; set; }
答案 0 :(得分:3)
是的,MemberwiseClone也会复制Checker
- 仅限字段。 MemberwiseClone无法知道Clone
方法的返回类型;因此,它的行为不能依赖它。
关于Clone实现与序列化之间的区别:MemberwiseClone
创建Tiles的浅层副本:如果Tile(或Checker)引用了某个对象,则Tile的克隆仍然引用相同的对象(而不是它的副本)。
另一方面,序列化代码是well known practice,用于创建电路板的深层复制:整个依赖对象树被序列化和反序列化。
当然,如果您的Tiles(或Checkers)包含带引用类型的字段,这只会产生影响。
答案 1 :(得分:2)
正如我所看到的,关于克隆,有四个主要类别的对象:
半可复制对象应该支持一个名为CloneBase的受保护虚拟方法,该方法将返回Object或基类类型(实际上并不重要);最低级别的CloneBase方法应调用MemberwiseClone并执行修复克隆对象所需的任何操作。任何支持克隆的派生类都应该有一个公共的Clone方法,它只调用CloneBase并对结果进行类型转换。在基类级别克隆之后修复和对象所需的任何派生类逻辑都应该覆盖CloneBase。
如果可能需要不支持克隆的派生类,则将public设为半可克隆类,并从该类继承CloneableWhatever除了添加公共Clone方法之外什么也不做。这样,非可克隆类可以从半可克隆类派生,可克隆类可以从CloneableWhatever派生。
答案 2 :(得分:1)
是的,它会 - polymorphism。