使用Linq生成要从另一个集合中删除的东西的集合

时间:2009-10-09 15:04:19

标签: c# linq collections loops

我熟悉在使用foreach循环(即“System.InvalidOperationException:Collection was modified”)循环它时修改集合的问题。但是,当我使用Linq创建一个要从字典中删除的键列表,然后遍历我的新List时,我得到了同样的异常,这对我没有意义。

之前的代码,引发了异常:

IEnumerable<Guid> keysToDelete = _outConnections.Where(
    pair => pair.Value < timeoutPoint
).Select(pair => pair.Key);

foreach (Guid key in keysToDelete)
{
    ...some stuff not dealing with keysToDelete...
    _outConnections.Remove(key);
}

之后的代码,有效:

List<Guid> keysToDelete = _outConnections.Where(
    pair => pair.Value < timeoutPoint
).Select(pair => pair.Key).ToList();

for (int i=keysToDelete.Count-1; i>=0; i--)
{
    Guid key = keysToDelete[i];
    ...some stuff not dealing with keysToDelete...
    _outConnections.Remove(key);
}

这是为什么?我觉得可能我的Linq查询并没有真正返回一个新的集合,而是原始集合的一些子集,因此它指责我在从{{1}中删除元素时修改集合keysToDelete }。

更新:以下修复也有效,感谢Adam Robinson:

_outConnections

1 个答案:

答案 0 :(得分:9)

你是对的。 LINQ使用所谓的“延迟执行”。除了构造查询表达式之外,声明您的LINQ查询实际上并不执行任何操作。直到您实际枚举列表中的查询被评估,并且它使用原始列表作为源。

但是,调用ToList()应创建一个与原始列表无关的全新列表。检查异常的调用堆栈,确保keysToDelete实际抛出它。