【发布时间】:2010-12-05 09:19:57
【问题描述】:
我熟悉在使用 foreach 循环(即“System.InvalidOperationException: Collection was modified”)循环时修改集合的问题。但是,对我来说,当我使用 Linq 创建要从字典中删除的键列表,然后循环遍历我的新列表时,我得到了同样的异常。
之前的代码,抛出异常:
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 查询并没有真正返回一个新集合,而是原始集合的某个子集,因此当我从 _outConnections 中删除一个元素时,它指责我修改了集合 keysToDelete。
更新:以下修复也有效,感谢 Adam Robinson:
List<Guid> keysToDelete = _outConnections.Where(
pair => pair.Value < timeoutPoint
).Select(pair => pair.Key).ToList();
foreach (Guid key in keysToDelete)
{
...some stuff not dealing with keysToDelete...
_outConnections.Remove(key);
}
【问题讨论】:
-
如果我可以告诉人们关于 LINQ 查询的一件事,那就是查询表达式的结果是查询本身,而不是查询的结果我>。这种常见的误解是 StackOverflow 上有关 LINQ 的相当一部分问题的基础。
-
当我发现 Linq 时,我想“哦,嘿,这让我可以在 Ruby 中做类似的事情!”,我仍然在内部考虑像
Select和Where这样的方法,就 Ruby 的 @ 而言987654329@ 和select,它们进行处理并返回新的结果集合。我必须开始在心理上将 Ruby 方法与看起来相似的 Linq 方法区分开来。
标签: c# linq collections loops