ziy*_*ang 3 c# abstract-class clone generic-list
我有一个基类:abstract class Base和一些派生类:class Derived: Base,所有数据成员都在基类中。我有另一个通用列表:List<Base> list。现在我想Clone()对列表进行操作。我读过这篇文章,但发现我的情况有点复杂。由于基类是抽象的,因此不能通过复制构造函数或实现接口来克隆列表的元素ICloneable。但由于所有数据成员都在基类中,因此在派生类中一次又一次地编写相同的代码进行克隆是多余的。完成这项工作的最佳方法是什么?感谢您提供提示。
更新:附简化源代码
public class Point : ICloneable
{
public int X { get; set; }
public int Y { get; set; }
public Point(int x, int y)
{ X = x; Y = y; }
public Point(Point p)
{
X = p.X; Y = p.Y;
}
public object Clone()
{
return MemberwiseClone();
}
}
public abstract class ObjectThatHasPosition : ICloneable
{
public Point CurrentPosition { get; set; }
public ObjectThatHasPosition(Point p)
{ CurrentPosition = new Point(p); }
public object Clone()
{
return MemberwiseClone();
}
}
public class Man : ObjectThatHasPosition
{
public Man(Point p) : base(p) { }
}
static class Extensions
{
public static List<ObjectThatHasPosition> Clone(this List<ObjectThatHasPosition> src)
{
List<ObjectThatHasPosition> dst = new List<ObjectThatHasPosition>(src.Count);
src.ForEach((item) => { dst.Add((ObjectThatHasPosition)item.Clone()); });
return dst;
}
}
static void Main(string[] args)
{
List<ObjectThatHasPosition> firstList = new List<ObjectThatHasPosition>();
firstList.Add(new Man(new Point(0, 0)));
List<ObjectThatHasPosition> anotherList = firstList.Clone();
firstList[0].CurrentPosition.X = 1;
}
Run Code Online (Sandbox Code Playgroud)
可以看到两个列表的元素是相同的。
我不明白为什么Base无法实施ICloneable:
public abstract class Base : ICloneable
{
public object Clone()
{
return MemberwiseClone();
}
}
Run Code Online (Sandbox Code Playgroud)
当在派生类上调用时,仍然会返回正确的实例(即与现有对象相同的类型)。派生类中的任何字段也将被复制 - 尽管是以浅层方式。作为一个具体的例子:
using System;
public abstract class BaseClass : ICloneable
{
public object Clone()
{
return MemberwiseClone();
}
}
public class Derived : BaseClass
{
private readonly string name;
public Derived(string name)
{
this.name = name;
}
public override string ToString()
{
return "Derived with name " + name;
}
}
class Test
{
static void Main(string[] args)
{
BaseClass b = new Derived("fred");
object clone = b.Clone();
Console.WriteLine(clone.ToString());
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:我怀疑你想要类似的东西:
public abstract class ObjectThatHasPosition : ICloneable
{
public Point CurrentPosition { get; set; }
public ObjectThatHasPosition(Point p)
{
CurrentPosition = p;
}
public object Clone()
{
var clone = (ObjectThatHasPosition) MemberwiseClone();
clone.CurrentPosition = (Point) CurrentPosition.Clone();
}
}
Run Code Online (Sandbox Code Playgroud)