Reputation: 141
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
Upvotes: 1
Views: 8457
Reputation: 96730
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,
...
};
}
Upvotes: 5
Reputation: 19842
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();
Upvotes: 1