所以我创建了一个我想删除的项目字典的投影。
var toRemoveList =
this.outputDic.Keys.Where(key =>
this.removeDic.ContainsKey(key));
正如我经常说的,如果我可以教人们关于 LINQ 的一件事,那就是: 查询表达式的结果是查询,而不是执行查询的结果。你现在有一个对象,它的意思是“字典的键,使得键是……某物”。不是那个查询的结果,而是那个查询。查询本身就是一个对象;它不会给你一个结果集,直到你要求一个。
然后你这样做:
foreach(var key in toRemoveList)
this.outputDic.Remove(key);
那么你正在做什么?您正在遍历查询。遍历查询会执行查询,因此查询会遍历原始字典。但是,当您迭代它时,您从字典中删除了一个项目,这是非法的。
imo,它甚至不应该首先发生。
你对世界应该是什么样子的看法很普遍,但按照你的方式去做会导致效率低下。让我们假设创建查询会立即执行查询,而不是创建查询对象。这是做什么的?
var query = expensiveRemoteDatabase
.Where(somefilter)
.Where(someotherfilter)
.OrderBy(something);
第一次调用Where
产生一个查询,然后在您的世界中执行该查询,从远程数据库中提取与该查询匹配的所有记录。然后第二个电话Where
说“哦,对不起,我的意思是在这里也应用这个过滤器,我们可以再次执行整个查询,这次使用第二个过滤器吗?” 然后计算整个记录集,然后我们说“哦,不,等等,我忘了告诉你,当你构建最后一个查询对象时,我们需要对它进行排序,所以数据库,你能运行第三次问我这个问题?”
现在也许你明白为什么查询会产生一个查询,然后直到它需要才执行?