当ObservableCollection中的副本为?</t>时,为什么List <t>中的值发生了变化

时间:2014-05-28 12:46:25

标签: c# windows-store-apps microsoft-metro observablecollection

// 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中的相同值。我无法弄清楚我做错了什么,因为第二行代码应该是一个复制构造函数?

1 个答案:

答案 0 :(得分: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对象本身,但它不会复制单个列表元素。注意,它并不那么简单,您的示例实际上可以如果类别为struct,则工作。

这是通常的行为,它被称为浅层复制。或者,您正在寻找的内容称为深层复制

您需要使用序列化手动创建副本,或者只需在 Category 类中创建copy-constructor。

这是一个很好的例子:

new ObservableCollection(dbCategories.Select(x => new Category(x)).ToList());