根据我从 C# 6.0 Cookbook 中读到的内容,最好的方法是创建自己的 ShallowClone 和 DeepClone 接口,然后实现它们。不建议使用 ICloneable 的原因是,对于 ICloneable 是创建 DeepClone 还是 ShallowClone 存在混淆,因此如果 Microsoft 的不起作用,请自行创建接口。
ShallowClone 正在重新创建对象,其所有属性都具有相同的引用(两个不同的对象引用相同的属性)
DeepClone 正在使用新属性重新创建对象。
要进行 ShallowClone,以下工作:
public ShallowClone ShallowCopy() => (ShallowClone)this.MemberwiseClone();
对于 DeepClone:
public DeepClone DeepCopy()
{
BinaryFormatter BF = new BinaryFormatter();
MemoryStream memStream = new MemoryStream();
BF.Serialize(memStream, this);
memStream.Flush();
memStream.Position = 0;
return (DeepClone)BF.Deserialize(memStream);
}
直接从书中偷来的,所以所有的功劳都在那里。我只记得这是它“应该”在 C# 中完成的方式。然而,可能仍然有更好的方法,尤其是在我们现在处于 C# 8.0 的情况下。
您可以只编写自己的 ShallowClone 和 DeepClone 方法,并分配每个属性或创建新属性,但这很乏味,因此上述方法如此有用。
所以想法是在要克隆的对象上实现这些接口,然后使用方法。
我正在考虑改用这些扩展方法,但它不起作用。我的想法是这样的:
public static class CloningExtention
{
public static T ShallowClone(this T obj) => (T)obj.MemberwiseClone(); // Doesn't work
public static T DeepClone(this T obj)
{
BinaryFormatter BF = new BinaryFormatter();
MemoryStream memStream = new MemoryStream();
BF.Serialize(memStream, this);
memStream.Flush();
memStream.Position = 0;
return (T)BF.Deserialize(memStream);
};
}
但 MemberwiseClone 是受保护的方法,因此扩展方法不起作用。为什么要保护它?我不知道,但如果我不得不猜测,那是因为有一个很好的理由说明你不应该在任何你喜欢的地方克隆对象。
但是,我仍然想演示它,所以你知道不要这样做。如果有人知道为什么要保护此方法,请告诉我。