C# 使用Linq生成要从另一个集合中删除的内容集合

C# 使用Linq生成要从另一个集合中删除的内容集合,c#,linq,collections,loops,C#,Linq,Collections,Loops,我熟悉使用foreach循环(即“System.invalidooperationexception:collection was modified”)在集合上循环时修改集合的问题。然而,当我使用Linq创建一个要从字典中删除的键列表,然后在新列表上循环时,我得到了相同的异常,这对我来说是没有意义的 之前的代码,该代码引发了异常: IEnumerable<Guid> keysToDelete = _outConnections.Where( pair => pair.V

我熟悉使用
foreach
循环(即“System.invalidooperationexception: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);
}

你说得对。LINQ使用所谓的“延迟执行”。声明LINQ查询实际上除了构造一个查询表达式之外,并没有做任何事情。直到您实际枚举了列表之后,查询才会被计算,并且它使用原始列表作为源


但是,调用
ToList()
应该会创建一个与原始列表无关的全新列表。检查异常的调用堆栈,以确保它实际上是由
keystelete
引发的。哎呀,忘记了我的部分修复涉及添加
ToList
。最初,我只是使用
IEnumerable
;更新了问题代码以反映这一点。Oho,根据你的第二段,我可以将我的修复更改为以下内容之一:1)删除
ToList
内容,只需在
IEnumerable
上使用我的
for
循环,或者2)保留
ToList
内容并切换回使用
foreach
循环,因为新列表是一个单独的集合。谢谢您不能使用
for
选项,因为
IEnumerable
不支持基于索引的访问。我建议在
ToList()
的结果上切换到
foreach
。同意。我不喜欢那些简单的
for
循环,因为它们看起来不像foreach那样安全。我将我的新解决方案(
ToList
foreach
)添加到问题中。如果我能告诉人们关于LINQ查询的一件事,那就是查询表达式的结果是查询本身,而不是查询的结果。这种常见的误解是关于StackOverflow上LINQ的大部分问题的基础。当我发现LINQ时,我想“哦,嘿,这让我可以在Ruby中做类似的事情!”,我仍然在内部根据Ruby的
映射和
选择
选择
等方法,进行处理并返回新的结果集合。我必须从思想上把Ruby方法与类似的Linq方法分开。
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);
}
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);
}