所以我创建了一个我想删除的项目字典的投影.
var toRemoveList =
this.outputDic.Keys.Where(key =>
this.removeDic.ContainsKey(key));
Run Code Online (Sandbox Code Playgroud)
然后我遍历从实际字典中删除的结果
foreach(var key in toRemoveList)
this.outputDic.Remove(key);
Run Code Online (Sandbox Code Playgroud)
但是在该foreach期间抛出一个异常,表示该循环期间修改了列表.但是,怎么这样呢?linq查询是否有点动态,每次字典更改时都会重新评估?查询结尾处的一个简单的.ToArray()调用解决了问题,但是imo,它甚至不应该首先出现.
Eri*_*ert 14
所以我创建了一个我想删除的项目字典的投影.
var toRemoveList =
this.outputDic.Keys.Where(key =>
this.removeDic.ContainsKey(key));
Run Code Online (Sandbox Code Playgroud)
正如我经常说的,如果我可以向人们传授关于LINQ的一件事,那就是: 查询表达式的结果是查询,而不是执行查询的结果.你现在有一个对象,意思是"字典的键,使得键是......某种东西".它不是该查询的结果,而是查询.查询本身就是一个对象; 在你要求之前,它不会给你一个结果集.
然后你这样做:
foreach(var key in toRemoveList)
this.outputDic.Remove(key);
Run Code Online (Sandbox Code Playgroud)
那么你正在做什么?您正在迭代查询.迭代查询执行查询,因此查询迭代原始字典.但是当你迭代它时,你从字典中删除一个项目,这是非法的.
imo,它甚至不应该首先发生.
你对世界应该是怎样的观点是一个普遍的看法,但按照自己的方式去做会导致效率低下.让我们假设创建查询立即执行查询而不是创建查询对象.这是做什么的?
var query = expensiveRemoteDatabase
.Where(somefilter)
.Where(someotherfilter)
.OrderBy(something);
Run Code Online (Sandbox Code Playgroud)
Where生成查询的第一个调用,然后在您的世界中执行,从远程数据库中下拉与该查询匹配的所有记录.然后第二次打电话Where说"哦,对不起,我本来也想在这里应用这个过滤器,我们可以再次进行整个查询,这次使用第二个过滤器吗?" 因此然后是整个记录集的计算,然后我们说:"哦,不,等一下,我忘了告诉你,当你建立了一个最后的查询对象,我们将需要对它进行排序,那么数据库,你可以运行这个问题第三次给我?"
现在也许您看到为什么查询生成一个查询,然后在需要之前不会执行?
| 归档时间: |
|
| 查看次数: |
740 次 |
| 最近记录: |