簡體   English   中英

如何克隆從C#中的抽象類派生的類實例的泛型列表?

[英]How to clone a generic list of instances of a class derived from an abstract class in C#?

我有一個基類: 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;
    }

可以看到兩個列表的元素相同。

我不明白為什么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();
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM