在以下方法中,当我将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
为什么?两者(here和here)的MSDN页面都说“元素按照它们被读取的顺序复制到ObservableCollection上该集合的普查员。“
答案 0 :(得分:2)
在第二种情况下,您实际上是在两次评估查询。一旦您使用foreach
,然后再创建ObservableCollection
。您将最终得到两组不同的对象,您可以通过在PlanningGridHeaderVM
构造函数中添加一些调试信息来验证这些对象。
第一次对查询结果进行迭代并没有主动完成它 - 没有这样的概念。但是,返回的对象将立即有资格进行垃圾回收,除非您的AddHandler
方法保留对它们的引用。
在第一种情况下,您只评估一次查询,因为ToList()
将具体化查询。它基本上是接受查询,评估它并记住结果 - 所以当你用foreach
迭代它然后从它创建一个ObservableCollection
时,这两个循环都将在相同的对象集合。