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);
}