• .NET 8 preview 7 中对JsonNode的一些优化
  • 发布于 2个月前
  • 200 热度
    0 评论
简介
在 .NET 8 preview 7 中对于 System.Text.Json 也做了一些优化,有一些针对 JsonNode 的新 API,我们来看下示例。

例子
DeepClone &&DeepEquals
新增了 DeepClone 来 clone 一个全新的 JsonNode,和 JsonNode.DeepEquals 来比较两个 JsonNode 的内容是否一致,在之前的版本中可能一般会通过 JsonNode 的 ToJsonString() 获取 JSON 字符串来进行比较,有了这个 API 之后就可以直接比较两个 JsonNode了
// 堆代码 duidaima.com
var node = JsonNode.Parse("""{"id": 1, "name": "test", "jobs": ["abc", "def"]}""");
ArgumentNullException.ThrowIfNull(node);
var node2 = node.DeepClone();
Console.WriteLine(node2.ToJsonString());
Console.WriteLine("JsonNode.DeepEquals(node, node2) ?? {0}", JsonNode.DeepEquals(node, node2));
输出结果如下:
{"id":1,"name":"test","jobs":["abc","def"]}
JsonNode.DeepEquals(node, node2) ?? True
JsonArray.GetValues
针对 JsonArray 添加了一个 GetValues<T>() 的方法来便捷的获取一个 IEnumerable<T> 对象
var jsonArray = new JsonArray(1, 2, 3, 2);
var values = jsonArray.GetValues<int>()
    .Where(i => i != 2);
foreach (var value in values)
{
    Console.WriteLine(value);
}
输出结果是:
1
3
实现源码也比较简单:
public IEnumerable<T> GetValues<T>()
{
  foreach (JsonNode jsonNode in this.List)
    yield return jsonNode is null ? (T) null : jsonNode.GetValue<T>();
}

GetPropertyName/GetElementIndex
如果我们当前的对象是 JsonObject 中的某一个属性值,我们可以通过 GetPropertyName 来获取当前 property 的名字,类似地我们当前的对象是 JsonArray 中的一个值,可以通过 GetElementIndex 来获取数组索引
var node = JsonNode.Parse("""{"id": 1, "name": "test", "jobs": ["abc", "def"]}""");
ArgumentNullException.ThrowIfNull(node);
Console.WriteLine(node.GetValueKind());
InvokeHelper.TryInvoke(() => Console.WriteLine(node.GetElementIndex()));
InvokeHelper.TryInvoke(() => Console.WriteLine(node.GetPropertyName()));
Console.WriteLine(node["id"]?.GetPropertyName());
Console.WriteLine(node["jobs"]?.AsArray()[1]?.GetElementIndex());
输出结果:

其它
认真观察的话会发现最后的两个 exception 信息有点不太对,这里算是一个 bug,提了一个 issue 应该是 parentNode,具体可以看 https://github.com/dotnet/runtime/issues/90474 目前已经修复,预计会在 RC 2 版本中修复
用户评论