Intro
在 .NET 8 preview 7 中对于 System.Text.Json 也做了一些优化,有一些针对 JsonNode 的新 API,我们来看下示例
Sample
DeepClone &&DeepEquals
新增了 DeepClone
来 clone 一个全新的 JsonNode
,和 JsonNode.DeepEquals
来比较两个 JsonNode 的内容是否一致,在之前的版本中可能一般会通过 JsonNode
的 ToJsonString()
获取 JSON 字符串来进行比较,有了这个 API 之后就可以直接比较两个 JsonNode
了.
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());
输出结果:
More
认真观察的话会发现最后的两个 exception 信息有点不太对,这里算是一个 bug,提了一个 issue 应该是 parentNode,具体可以看 https://github.com/dotnet/runtime/issues/90474 目前已经修复,预计会在 RC 2 版本中修复