我在处理以下代码时遇到一些问题:
AllAgents.CollectionChanged += (sender, e) =>
{
if (e.Action != NotifyCollectionChangedAction.Remove) return;
foreach (var s in AllSnapshots)
{
foreach (var stat in s.Stats.Where(stat => stat.Model.Agent == null))
s.Stats.Remove(stat);
}
};
这当然抛出一个“收藏被修改;枚举操作可能无法执行。”例外对我来说是完全有意义的。问题是,从ObservableCollection中移除Model.Agent属性为空的所有项的最佳方法是什么?我也对其他解决方案持开放态度,基本上,当从AllAgents集合中删除代理时,我需要从AllSnapshots.Stats集合中删除引用该代理的所有条目。
5条答案
按热度按时间zbdgwd5y1#
从这样的集合中删除项的最好方法是使用标准的
for
循环构造并向后迭代集合。由于不再依赖枚举数来循环访问集合,因此可以安全地修改它,而不会干扰循环。反向迭代可以防止删除在循环过程中干扰索引,否则可能会导致某些元素最终无法被删除。
p4tfgftt2#
问题是你在迭代和删除,然后尝试再次迭代。
ObservableCollection
不支持这一点,因为它不会跟踪哪些元素被删除。将
foreach
替换为一个不依赖于集合不被修改的标准计数,仅此而已。这个解决方案不同于Sam I am的回复,因为它不使用额外的内存来创建另一个列表(如果你的元素数量足够大,这可能会非常昂贵)。
x6492ojm3#
我可能要做的是生成一个要删除的统计信息列表,然后在一个单独的foreach循环中将它们全部删除
pb3s4cty4#
如果每个快照的统计数据数量相当少,我可能会这样做:
因此,这将构建一个新的集合,其中包含 * are not * null的元素。如果统计数据列表相当大,你也可以这样做:
或者,如果你想在未来做更多的证明,你可以写一个扩展方法来做这样的事情:
它会被这样称呼:
7uzetpgm5#
现在在observablecollection中有一个removeall方法,正如我在.net core 7中看到的那样-只是在任何人开始意外地重新发明轮子时提到它(我也一直在做-只是想帮忙)。