我想在observablecollection中复制一个列表项。当我这样做时:
TreasureCards[TreasureCards.Count - 1] = TreasureCards[CardPosition];
它会创建特定列表项的副本,但随后会在我的UI中进行链接。因此,如果我更改新的重复项目的名称,它将更改原始名称。我知道我可以逐个完成每个属性(见下文),但有没有办法只复制整个项目?
TreasureCards[TreasureCards.Count - 1].Name = TreasurecCards[CardPosition].Name;
TreasureCards[TreasureCards.Count - 1].Type= TreasurecCards[CardPosition].Type;
// etc
答案 0 :(得分:4)
您没有复制该对象。您正在创建对该对象的新引用。仍然只有一个对象;现在,您的集合中有两个对它的引用,对象的任何更改都会被两个引用反映出来。
要创建新对象,您可以在MemberwiseClone()
派生的任何内容上调用Object
。此方法返回一个新实例,复制原始对象中所有字段的值。所以你要这样做:
TreasureCards[TreasureCards.Count - 1] = TreasureCards[CardPosition].MemberwiseClone();
此方法有两个限制。首先,它是浅拷贝,即原始对象中的任何参考字段都复制了它们的值。因此,如果a.Foo
是对Bar
对象的引用,则a.MemberwiseClone().Foo
将引用相同的Bar
对象。其次,该方法只是复制字段;它不会调用新对象的构造函数。根据班级的设计,这要么不重要,要么真的很大。
通常,使类实现ICloneable
并明确实现Clone()
方法更安全,例如:
public TreasureCard Clone()
{
return new TreasureCard
{
Name = this.Name,
Type = this.Type,
...
};
}
答案 1 :(得分:1)
它们没有链接,它们是同一个实例。您所做的只是将对相同数据的引用复制到数组中的另一个位置。
您需要做的是实现一些Clone方法,该方法生成原始实例的副本,但作为另一个实例。这个SO post可能会有所帮助。
然后你会做这样的事情:
TreasureCards[TreasureCards.Count - 1] = TreasureCards[CardPosition].Clone();