1

I want to duplicate a list item in an observablecollection. When I do:

            TreasureCards[TreasureCards.Count - 1] = TreasureCards[CardPosition];

It creates a copy of the specific list item but then they are linked in my UI. So if I change the new duplicated item's name, it changes the originals name. I know I could do each of the properties one by one (see below) but is there a way to just copy the entire item?

    TreasureCards[TreasureCards.Count - 1].Name = TreasurecCards[CardPosition].Name;
    TreasureCards[TreasureCards.Count - 1].Type= TreasurecCards[CardPosition].Type;

// etc
Stacey
  • 141
  • 3
  • 12

2 Answers2

5

You aren't duplicating the object. You're creating a new reference to the object. There's still only one object; now there are two references to it in your collection, and any change to the object is reflected by both references.

To create a new object, you can call MemberwiseClone() on anything that derives from Object. This method returns a new instance, copying the values from all fields in the original object. So you'd do:

TreasureCards[TreasureCards.Count - 1] = TreasureCards[CardPosition].MemberwiseClone();

There are two limitations with this method. First, it's a shallow copy, i.e. any reference fields in the original object have their values copied. So if a.Foo is a reference to a Bar object, a.MemberwiseClone().Foo will refer to the same Bar object. Second, the method just copies the fields; it doesn't call the new object's constructor. Depending on the design of the class, this is either unimportant or a Really Big Deal.

Usually, it's safer to make the class implement ICloneable and explicitly implement a Clone() method, e.g.:

public TreasureCard Clone()
{
   return new TreasureCard
   {
      Name = this.Name,
      Type = this.Type,
      ...
   };
}
Robert Rossney
  • 94,622
  • 24
  • 146
  • 218
  • Sorry for my delay in response I haven't had a chance to work on my project until now. Thank you for your help Robert - I was able to get my clone to work! – Stacey Mar 25 '11 at 02:11
1

They aren't linked, they are the same instance. All you're doing is copying a reference to the same data to another position in the array.

What you need to do is implement some Clone method that makes a copy of the original instance but as another instance. This SO post might help.

Then you would do something like this:

 TreasureCards[TreasureCards.Count - 1] = TreasureCards[CardPosition].Clone();
Community
  • 1
  • 1
CodingGorilla
  • 19,612
  • 4
  • 45
  • 65