使用Newtonsoft.Json遍历json个IM:

var jObject = JObject.Parse(sr.ReadToEnd());
foreach (KeyValuePair<string, JToken?> superior in jObject) {
...
}

正如您在上面看到的,JObject实现了IEnumerable<KeyValueString<string, JToken?>>个.但当JToken在枚举中为空时,我找不到任何 case .

我试着这样做:

{

}
{
   "A": { }
}
{
   "A": ""
}
{
    "A": null
}

...而且它总是不是空的. 那么,为什么枚举器使用JToken?呢?

推荐答案

你永远不会得到一个空JToken.正如this post所说,Newtonsoft JSON被设计为不允许任何null值.每个null值都被转换为Null类型的JValue实例.

为了更有说服力,看看GetEnumeratorsource code中是如何实施的:

    public IEnumerator<KeyValuePair<string, JToken?>> GetEnumerator()
    {
        foreach (JProperty property in _properties)
        {
            yield return new KeyValuePair<string, JToken?>(property.Name, property.Value);
        }
    }

JProperty.Value的类型是JToken,而不是JToken?.

我怀疑它实现IDictionary<string, JToken?>而不是IDictionary<string, JToken>的原因是因为索引器被设计为在找不到键时返回NULL,并且也接受NULL值.

var token = someJObject["key"];
// unlike a Dictionary<TKey, TValue>, 
// token is null if "key" is not a key in the JSON object,
// instead of throwing an exception

// you can also set a particular key as null directly, instead of making a JValue representing "null"
someJObject["key"] = null;

IDictionary<string, JToken>要求索引器是不可空的JToken类型,因此它无法实现.

Csharp相关问答推荐

我应该将新的httpReportMessage()包装在using声明中吗?

为什么我不能更改尚未设置的模拟对象属性的值?

始终保留数组中的最后N个值,丢弃最老的

如何修改中间件或其注册以正确使用作用域服务?

实体核心框架--HasColumnType和HasPrecision有什么不同?

集合表达式没有目标类型

当索引和外键是不同的数据类型时,如何设置导航属性?

是否由DI容器自动处理由ActivatorUilties.CreateInstance()创建的服务?

如何在不复制或使用输出的情况下定义项目依赖

Google OAuth令牌交换在.Net中不起作用

链接到字典字符串.拆分为(.Key,.Value)

为什么ReadOnlySpan;T&>没有Slice(...)的重载接受Range实例的?

Blazor Server/.NET 8/在初始加载时调用异步代码是否冻结屏幕,直到第一次异步调用完成?

如何在特定环境中运行dotnet测试?

将字符串类型日期输入(yyyy-mm-ddthh:mm:ss)转换为MM/dd/yyyy格式

仅在Blazor Web App中覆盖生产的基本路径(.NET8中的_Hosts.cshtml文件功能?)

SharpZipLib在文件名前加上目录名,生成tar.gz

在使用.NET EF Core DbContext属性之前,是否应使用null判断

当我在Git中暂存文件更改时,它们会消失

C#如何替换两个XML元素值?