Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/328.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在foreach循环中修改集合时发生异常_C#_Foreach - Fatal编程技术网

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!