复制ObservableCollection项

时间:2011-03-23 16:34:55

标签: c# wpf observablecollection

我想在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

2 个答案:

答案 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();