Дублируйте элемент ObservableCollection - PullRequest
1 голос
/ 23 марта 2011

Я хочу продублировать элемент списка в наблюдаемой коллекции. Когда я делаю:

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

Создает копию определенного элемента списка, но затем они связываются в моем пользовательском интерфейсе. Поэтому, если я изменю имя нового дублированного элемента, это изменит имя оригинала. Я знаю, что могу выполнить каждое из свойств по одному (см. Ниже), но есть ли способ просто скопировать весь элемент?

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

// etc

Ответы [ 2 ]

4 голосов
/ 23 марта 2011

Вы не дублируете объект. Вы создаете новую ссылку на объект. Там все еще только один объект; теперь в вашей коллекции есть две ссылки на него, и любое изменение объекта отражается обеими ссылками.

Чтобы создать новый объект, вы можете вызвать 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 голос
/ 23 марта 2011

Они не связаны, это один и тот же экземпляр.Все, что вы делаете, это копируете ссылку на те же данные в другую позицию в массиве.

Что вам нужно сделать, это реализовать некоторый метод Clone, который создает копию исходного экземпляра, но в качестве другого экземпляра.Этот SO post может помочь.

Тогда вы бы сделали что-то вроде этого:

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