我熟悉在使用foreach
循环(即“System.InvalidOperationException:集合已被修改”)循环时修改集合的问题。然而,当我使用Linq创建一个从字典中删除的键列表,然后遍历我的新列表时,我得到相同的异常,这对我没有任何意义。使用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查询不是真的返回一个新的集合,而是原始集合的一部分,因此它指责我修改集合keysToDelete
,当我从_outConnections
中删除元素时。
更新:以下修复也适用,由于亚当·罗宾逊:
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的很大一部分问题的基础。 – 2009-10-09 17:14:39
当我发现Linq时,我想“嘿,这让我做了像Ruby一样的东西!”,而且我仍然在内部按照Ruby的'map'和'select'的方式考虑像'Select'和'Where'这样的方法,它处理并返回一个新的结果集合。我将不得不从精神上将Ruby方法与类似的Linq方法分离开来。 – 2009-10-09 17:33:25