我熟悉在使用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
答案 0 :(得分:9)
你是对的。 LINQ使用所谓的“延迟执行”。除了构造查询表达式之外,声明您的LINQ查询实际上并不执行任何操作。直到您实际枚举列表中的查询被评估,并且它使用原始列表作为源。
但是,调用ToList()
应创建一个与原始列表无关的全新列表。检查异常的调用堆栈,确保keysToDelete
实际抛出它。