C# 在foreach循环中修改集合时发生异常
我知道在C# 在foreach循环中修改集合时发生异常,c#,foreach,C#,Foreach,我知道在foreach中不修改集合的基本原则,这就是为什么我会这样做: public void UpdateCoverages(Dictionary<PlayerID, double> coverages) { // TODO: temp var keys = coverages.Select(pair => pair.Key); foreach (var key in keys) {
foreach
中不修改集合的基本原则,这就是为什么我会这样做:
public void UpdateCoverages(Dictionary<PlayerID, double> coverages)
{
// TODO: temp
var keys = coverages.Select(pair => pair.Key);
foreach (var key in keys)
{
coverages[key] = 0.84;
}
}
public void updatecorerages(字典覆盖率)
{
//待办事项:临时工
var Key=coverage.Select(pair=>pair.Key);
foreach(var键入键)
{
覆盖率[关键点]=0.84;
}
}
以及:
class PlayerID:IEquatable
{
公共播放器ID(字节值)
{
价值=价值;
}
公共字节值{get;private set;}
公共布尔等于(玩家ID其他)
{
返回值==其他.Value;
}
}
首先,我保存了所有的密钥,以避免修改集合
异常,然后再进行检查。但我仍然有一个我无法理解的例外
如何纠正此问题,以及是什么原因导致此问题
首先我保存了所有的钥匙
不,你没有keys
是一个实时序列,当集合被foreach
迭代时,它会主动迭代集合。要创建密钥的独立副本,需要在末尾添加.ToList()
(或类似内容):
var keys = coverages.Select(pair => pair.Key).ToList();
虽然就我个人而言,我可能会:
var keys = new PlayerID[coverages.Count];
coverages.Keys.CopyTo(keys, 0);
(允许正确的长度分配和内存拷贝)
什么是现场直播
Select
方法在另一个上创建非缓冲假脱机迭代器。。。这是一件非常复杂的事情,但基本上是:当您第一次开始迭代var-key-in-keys
时,它会获取coverages
(又称coverages.GetEnumerator()
)的内部序列,然后每次foreach
请求下一项时,它都会请求下一项。是的,听起来很复杂。好消息是C#编译器自动内置了它,并为您生成状态机等。所有这些都主要使用产生返回
语法完成。Jon Skeet在《C#》的第6章中对此进行了深入的讨论。IIRC这曾经是“免费章节”,但现在不是了
但请考虑以下内容:
static IEnumerable<int> OneTwoOneTwoForever()
{
while(true) {
yield return 1;
yield return 2;
}
}
什么是现场直播?
static IEnumerable<int> OneTwoOneTwoForever()
{
while(true) {
yield return 1;
yield return 2;
}
}
var firstTwenty = OneTwoOneTwoForever().Take(20).ToList(); // works!