ObservableCollection的IEnumerable ctor最终确定了集合,但IList ctor却没有

时间:2013-11-04 06:53:19

标签: c# garbage-collection observablecollection

在以下方法中,当我将IEnumerable结果复制到包含ToList()的列表时,{strong>在ObservableCollection的{​​{>>中没有调用终结符 1}}构造函数,IList视图模型仅在程序关闭时完成:

IDisposable

但是,当我直接在private void ReadHeaders() { IList<PlanningGridHeaderVM> viewModelSet = (from header in _planningGridService.ReloadHeaders().OrderBy(x => x.PlanNumber) select new PlanningGridHeaderVM((PlanningGridHeader)header)).ToList(); foreach (PlanningGridHeaderVM headerVM in viewModelSet) { ItemEditedEventManager.AddHandler(headerVM, OnItemEdited); PropertyChangedEventManager.AddHandler(headerVM, OnPropertyChanged, string.Empty); } this.ViewModels = new ObservableCollection<PlanningGridHeaderVM>(viewModelSet); CollectionChangedEventManager.AddHandler(this.ViewModels, this.OnCollectionChanged); } 的{​​{1}}构造函数中使用IEnumerable结果时,我的调试输出会通知我所有ObservableCollection视图模型项当时GC被最终确定(这让我很困惑)。

尽管如此,我仍然可以在屏幕上获得所需的集合,并且在程序关闭时,它们都会再次完成(这次,正如预期的那样):

IEnumerable

为什么?两者(herehere)的MSDN页面都说“元素按照它们被读取的顺序复制到ObservableCollection上该集合的普查员。“

1 个答案:

答案 0 :(得分:2)

在第二种情况下,您实际上是在两次评估查询。一旦您使用foreach,然后再创建ObservableCollection。您将最终得到两组不同的对象,您可以通过在PlanningGridHeaderVM构造函数中添加一些调试信息来验证这些对象。

第一次对查询结果进行迭代并没有主动完成它 - 没有这样的概念。但是,返回的对象将立即有资格进行垃圾回收,除非您的AddHandler方法保留对它们的引用。

在第一种情况下,您只评估一次查询,因为ToList()具体化查询。它基本上是接受查询,评估它并记住结果 - 所以当你用foreach迭代它然后从它创建一个ObservableCollection时,这两个循环都将在相同的对象集合。