列表有更好的深度克隆方法吗? [复制]
Posted
技术标签:
【中文标题】列表有更好的深度克隆方法吗? [复制]【英文标题】:Is there any better deep clone methods for list? [duplicate] 【发布时间】:2017-11-03 22:09:55 【问题描述】:所以我需要一种深度克隆的方法。我希望一张卡片列表与另一张卡片列表相同,但我还想修改其中一个克隆。
我做了一个方法来复制这样的列表:
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 方法)。
有没有人知道如何简单地克隆一个列表对象?
【问题讨论】:
您可以使用cards.ToList()
克隆列表,但如果Card
是引用类型,您还需要克隆每个列表元素以获得深层副本。
您的方法不是深度克隆,因为所有Card
实例都没有被克隆,而只是复制到另一个列表(假设它们不是结构)。
我只想指出,由于您的 Copy 函数创建并返回 new List<Card>()
,因此您实际上不需要先初始化 _cards。您可以像这样使用您的函数:_thrownCards = new List<Card>(); ...; _cards = Copy(_thrownCards); _thrownCards.Clear();
另外,您在 Copy 函数中实际执行的操作是浅层克隆。这是一个*** question,关于两者之间的区别。
【参考方案1】:
这不是真正的深拷贝,因为 Card
实例仍然相同,只是列表不同。你可以更简单:
List<Card> cloneList = cards.ToList();
您还需要“复制”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());
【讨论】:
您是否建议将复制方法放在Card
本身上? cloneList.Add(card.DeepCopy())
@TimSchmelter 抱歉,出现错误并误解了我自己的结构。这很好用,所以我将其标记为解决方案!【参考方案2】:
要拥有深拷贝,你需要有这样的东西:
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;
当然,如果property1
和property2
也是引用类型的对象,那你就得更深入了。
【讨论】:
【参考方案3】:怎么样
List<Card> _cards = _thrownCards.ConvertAll(Card => new Card(<card parameters here>));
【讨论】:
【参考方案4】:不同于浅我们只复制引用时的复制
public List<Card> Copy(List<Card> cards)
return cards.ToList();
如果是 deep 副本,我们必须克隆 每个项目:
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();
【讨论】:
以上是关于列表有更好的深度克隆方法吗? [复制]的主要内容,如果未能解决你的问题,请参考以下文章