Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何克隆从C#中的抽象类派生的类的通用实例列表?_C#_Clone_Abstract Class_Generic List - Fatal编程技术网

如何克隆从C#中的抽象类派生的类的通用实例列表?

如何克隆从C#中的抽象类派生的类的通用实例列表?,c#,clone,abstract-class,generic-list,C#,Clone,Abstract Class,Generic List,我有一个基类:抽象类base和一些派生类:类派生:base,所有数据成员都在基类中。我有另一个通用列表:列表列表。现在我想对列表执行Clone()操作。我读过,但发现我的情况有点复杂。由于基类是抽象的,因此不能通过复制构造函数或实现ICloneable接口来克隆列表的元素。但由于所有数据成员都在基类中,因此在派生类中反复编写相同的代码进行克隆是多余的。做这项工作最好的方法是什么?谢谢你的提示 更新:附加简化源代码 public class Point : ICloneable { pub

我有一个基类:
抽象类base
和一些派生类:
类派生:base
,所有数据成员都在基类中。我有另一个通用列表:
列表列表
。现在我想对列表执行
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;
    }
公共类点:iClonable
{
公共整数X{get;set;}
公共整数Y{get;set;}
公共点(整数x,整数y)
{X=X;Y=Y;}
公共点(p点)
{
X=p.X;Y=p.Y;
}
公共对象克隆()
{
返回MemberwiseClone();
}
}
具有以下位置的公共抽象类对象:ICloneable
{
公共点当前位置{get;set;}
具有位置的公共对象(p点)
{CurrentPosition=新点(p);}
公共对象克隆()
{
返回MemberwiseClone();
}
}
公共类人:有位置的对象
{
公众人物(p点):基地(p){}
}
静态类扩展
{
公共静态列表克隆(此列表src)
{
列表dst=新列表(src.Count);
src.ForEach((item)=>{dst.Add((objectthasposition)item.Clone();});
返回dst;
}
}
静态void Main(字符串[]参数)
{
List firstList=新列表();
添加(新的人(新的点(0,0));
List anotherList=firstList.Clone();
firstList[0]。CurrentPosition.X=1;
}

可以看出,两个列表的元素是相同的

我不明白为什么
Base
不能实现
ICloneable

public abstract class Base : ICloneable
{
    public object Clone()
    {
        return MemberwiseClone();
    }
}
当对派生类调用时,它仍将返回正确的实例(即与现有对象相同的类型)。派生类中的任何字段也会被复制,尽管复制的方式很浅。作为一个具体例子:

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());
    }
}
编辑:我想你想要的是:

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();
    }
}

我不明白为什么
Base
不能实现
ICloneable

public abstract class Base : ICloneable
{
    public object Clone()
    {
        return MemberwiseClone();
    }
}
当对派生类调用时,它仍将返回正确的实例(即与现有对象相同的类型)。派生类中的任何字段也会被复制,尽管复制的方式很浅。作为一个具体例子:

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());
    }
}
编辑:我想你想要的是:

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();
    }
}

请解释为什么“无法通过…实现IClonable接口进行克隆”。抽象类中没有任何东西可以阻止接口的实现(即,如果您想强制派生类实现它,则通过抽象函数…),我认为Clone()必须调用一个复制构造函数,所以…您还可以在Base中实现一个复制构造函数,可通过继承的类构造函数调用。也没有什么能阻止这一点。请解释为什么“不能通过…实现IClonable接口进行克隆”。抽象类中没有任何东西可以阻止接口的实现(即,如果您想强制派生类实现它,则通过抽象函数…),我认为Clone()必须调用一个复制构造函数,所以…您还可以在Base中实现一个复制构造函数,可通过继承的类构造函数调用。也没有什么可以阻止它。但是我的代码仍然不起作用,我看不出问题出在哪里(源代码附在后面)。@ziyung:你希望MemberwiseClone做一个深度复制吗?没有。如果你不想要浅显的拷贝,你需要自己做那部分。请看我的编辑。我认为可以编写MemberwiseClone的递归版本,通过反射机制进行深度复制。@Ziyung:是的,这是可能的。不过,在大多数情况下,这会有点过分-最好在子类中覆盖
Clone
,并显式克隆您真正想要克隆的成员。但我的代码仍然不起作用,我看不出问题出在哪里(源代码已附加)。@ziyung:您希望MemberwiseClone进行深度复制吗?没有。如果你不想要浅显的拷贝,你需要自己做那部分。请看我的编辑。我认为可以编写MemberwiseClone的递归版本,通过反射机制进行深度复制。@Ziyung:是的,这是可能的。但在大多数情况下,这样做会有点过头——最好在子类中重写
Clone
,并显式克隆您真正想要克隆的成员。