是否有更好的深度克隆方法列表?

时间:2017-06-02 13:15:50

标签: c# deep-copy

所以我需要一种深度克隆的方法。我想要一张卡片列表等于另一张卡片列表,但我还想修改其中一个克隆。

我制作了一个复制列表的方法:

    public List<Card> Copy(List<Card> cards)
    {
        List<Card> clone = new List<Card>();
        foreach (var card in cards)
        {
            clone.Add(card);
        }
        return clone;
    }

并像这样使用它:

        _cards = new List<Card>();
        _thrownCards = new List<Card>();

        _cards = Copy(_thrownCards);
        _thrownCards.Clear();

我没有C#的经验,但不知怎的,我的直觉告诉我,我的复制方法可以变得更简单。没有其他方法可以深度复制列表吗?我尝试使用MemberWiseClone,但是只创建了对同一个对象的引用,而不是克隆它(可能我误解了MemberWiseClone方法)。

有没有人知道如何简单地克隆列表对象?

4 个答案:

答案 0 :(得分:6)

这不是真正的深层复制,因为Card实例仍然相同,只有列表不同。你可以这么简单:

List<Card> cloneList = cards.ToList();

你需要&#34;复制&#34; Card个实例的所有属性:

public List<Card> Copy(List<Card> cards)
{
    List<Card> cloneList = new List<Card>();
    foreach (var card in cards)
    {
        Card clone = new Card();
        clone.Property1 = card.Property1;
        // ... other properties
        cloneList.Add(clone);
    }
    return cloneList;
}

您还可以提供一个工厂方法来创建给定Card实例的克隆:

public class Card
{
    // ...

    public Card GetDeepCopy()
    {
        Card deepCopy = new Card(); 
        deepCopy.Property1 = this.Property1;
        // ...
        return deepCopy;
    }
}

然后,您将此逻辑封装在一个可以访问private成员(字段,属性,构造函数)的位置。将上面Copy方法中的行更改为:

cloneList.Add(card.GetDeepCopy()); 

答案 1 :(得分:1)

要获得深层复制,您需要具有类似的东西:

public List<Card> Copy(List<Card> cards)
{
    List<Card> clone = new List<Card>();
    foreach (var card in cards)
    {
        clone.Add(new Card 
        {
          property1 = card.property1;
          property2 = card.property2; // and so on
        });
    }
    return clone;
}

当然,如果property1property2也是参考类型的对象,那么您必须更深入。

答案 2 :(得分:0)

这样的东西
List<Card> _cards = _thrownCards.ConvertAll(Card => new Card(<card parameters here>));

答案 3 :(得分:0)

与我们仅复制引用时副本不同

 public List<Card> Copy(List<Card> cards) {
   return cards.ToList();
 }

如果是副本,我们必须克隆每个项目

 public List<Card> Copy(List<Card> cards) {
   return cards
     .Select(card => new Card() {
        //TODO: put the right assignment here  
        Property1 = card.Property1,
        ...
        PropertyN = card.PropertyN,
     }) 
     .ToList();
 }