You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何正确移除JsonNode?解决枚举修改集合异常

遍历JsonNode对象时移除元素的正确写法

在.NET 6中遍历JsonNode解析得到的JsonObject时,直接在循环内移除元素会触发InvalidOperationException——这是因为枚举集合的过程中,不允许修改集合本身的结构(添加/删除元素)。

复现代码

string jsonString =
    @"{
  ""Date"": ""2019-08-01T00:00:00"",
  ""Temperature"": 25,
  ""Summary"": ""Hot"",
  ""DatesAvailable"": [
    ""2019-08-01T00:00:00"",
    ""2019-08-02T00:00:00""
  ],
  ""TemperatureRanges"": {
      ""Cold"": {
          ""High"": 20,
          ""Low"": -10
      },
      ""Hot"": {
          ""High"": 60,
          ""Low"": 20
      }
  }
}";
JsonNode jDataSet = JsonNode.Parse(jsonString)!;
var dataSet = jDataSet.AsObject();
foreach (var entry in dataSet)
{
    if (entry.Key == "TemperatureRanges")
    {
        entry.Value.AsObject().Remove("Hot");
    }
    else if (entry.Key == "Date")
    {
        dataSet.Remove(entry.Key); // 此处触发异常
    }
}

异常信息

System.InvalidOperationException: Collection was modified; enumeration operation may not execute.
   at System.Collections.Generic.List`1.Enumerator.MoveNextRare()
   at System.Collections.Generic.List`1.Enumerator.MoveNext()
   at System.Text.Json.JsonPropertyDictionary`1.GetEnumerator()+MoveNext()
   at Tests.UnitTest1.Test2() in C:\Users\malat\project\tests\Tests\UnitTest1.cs:line 43

使用的.NET版本

> dotnet --version
6.0.408

解决方法

和普通集合的处理逻辑一致,核心是避免在枚举原集合的同时修改它,以下两种方法都可以解决问题:

方法1:先收集待删除的键,再批量移除

先遍历一次集合,把需要删除的键存到一个独立列表里,再遍历这个列表执行删除操作:

string jsonString =
    @"{
  ""Date"": ""2019-08-01T00:00:00"",
  ""Temperature"": 25,
  ""Summary"": ""Hot"",
  ""DatesAvailable"": [
    ""2019-08-01T00:00:00"",
    ""2019-08-02T00:00:00""
  ],
  ""TemperatureRanges"": {
      ""Cold"": {
          ""High"": 20,
          ""Low"": -10
      },
      ""Hot"": {
          ""High"": 60,
          ""Low"": 20
      }
  }
}";
JsonNode jDataSet = JsonNode.Parse(jsonString)!;
var dataSet = jDataSet.AsObject();

// 第一步:收集所有需要删除的键
var keysToRemove = new List<string>();
foreach (var entry in dataSet)
{
    if (entry.Key == "TemperatureRanges")
    {
        // 子对象的修改不影响当前集合枚举,可直接操作
        entry.Value.AsObject().Remove("Hot");
    }
    else if (entry.Key == "Date")
    {
        keysToRemove.Add(entry.Key);
    }
}

// 第二步:批量删除
foreach (var key in keysToRemove)
{
    dataSet.Remove(key);
}

方法2:反向遍历索引

把集合的键转成列表后,从最后一个元素往前遍历,这样删除元素不会影响后续遍历的索引位置:

string jsonString =
    @"{
  ""Date"": ""2019-08-01T00:00:00"",
  ""Temperature"": 25,
  ""Summary"": ""Hot"",
  ""DatesAvailable"": [
    ""2019-08-01T00:00:00"",
    ""2019-08-02T00:00:00""
  ],
  ""TemperatureRanges"": {
      ""Cold"": {
          ""High"": 20,
          ""Low"": -10
      },
      ""Hot"": {
          ""High"": 60,
          ""Low"": 20
      }
  }
}";
JsonNode jDataSet = JsonNode.Parse(jsonString)!;
var dataSet = jDataSet.AsObject();

// 把键转成列表,避免枚举时集合变化
var keys = dataSet.Keys.ToList();
// 从后往前遍历索引
for (int i = keys.Count - 1; i >= 0; i--)
{
    var key = keys[i];
    if (key == "TemperatureRanges")
    {
        dataSet[key].AsObject().Remove("Hot");
    }
    else if (key == "Date")
    {
        dataSet.Remove(key);
    }
}

内容的提问来源于stack exchange,提问作者malat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 17:57:37