Почему значение в List <T> изменяется, если есть копии в ObservableCollection?

1
// Get list from DB    
List<Category> dbCategories = DatabaseWrapper.GetCategories();
...
// COPY values to Obs.Col.
var shownCategries = new ObservableCollection<Category>(dbCategories);

// This also changes the value in 'dbCatagories'.
shownCategories[0].Name = "Hej";

Я хочу иметь возможность изменить значение в obs.col. без изменения того же значения в dbCategories. Я не могу понять, что я делаю неправильно, так как вторая строка кода должна быть конструктором копирования?

Теги:
observablecollection
windows-store-apps
microsoft-metro

1 ответ

3
Лучший ответ

Ничто не может объяснить больше, чем исходный код. Вы делаете недопустимые предположения.

А именно:

private void CopyFrom(IEnumerable<T> collection)
{
  IList<T> items = this.Items;
  if (collection == null || items == null)
    return;
  foreach (T obj in collection)
    items.Add(obj);
}

а также

public ObservableCollection(List<T> list)
  : base(list != null ? (IList<T>) new List<T>(list.Count) : (IList<T>) list)
{
  this.CopyFrom((IEnumerable<T>) list);
}

как вы можете видеть, "конструктор копирования" действительно делает копию самого объекта LIST, но он не делает копию отдельных элементов списка. Обратите внимание, что это не так просто, ваш пример может действительно работать, если Category будет struct.

Это обычное поведение, и оно называется мелким копированием. Альтернативно, то, что вы ищете, называется глубоким копированием

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

Это будет хорошим примером:

new ObservableCollection(dbCategories.Select(x => new Category(x)).ToList());
  • 0
    Отличный ответ, спасибо.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню