Skip to content

Commit a6e8f4c

Browse files
committed
feat: 添加 foreach 遍历支持
1 parent ac5e408 commit a6e8f4c

5 files changed

Lines changed: 122 additions & 7 deletions

File tree

README.md

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,9 @@ string s1 = json.s;
6262
MyClass obj = json.a.b; //将 json.a.b 反序列化到类型 MyClass
6363
6464
//获取内部的原始 System.Text.Json.Nodes.* 对象
65-
JsonArray array = json.ArrayProperty;
66-
JsonObject obj = json.ObjectProperty;
67-
JsonNode node = json.NodeProperty;
65+
JsonArray array = json.XXArrayProperty; //显式类型转换
66+
JsonObject obj = json.XXXObjectProperty; //显式类型转换
67+
JsonNode node = json.XXXXNodeProperty; //显式类型转换
6868
```
6969

7070
## 修改 `JSON` 对象
@@ -103,14 +103,37 @@ var b4 = JSON.isUndefined(() => json.a.b.c.e.f.g.h.i.j.k);
103103

104104
```C#
105105
//遍历Array
106+
107+
//foreach遍历
108+
foreach (var item in json.XXArrayProperty)
109+
{
110+
}
111+
106112
//显式赋值类型
107113
IEnumerable<dynamic> enumerable = json.Array;
114+
108115
//通过IDynamicEnumerable
109116
var enumerable = ((IDynamicEnumerable)json.Array).AsEnumerable();
110117

111118
//遍历属性
119+
120+
//foreach遍历
121+
foreach (var item in json.XXArrayProperty)
122+
{
123+
//item.Key
124+
//item.Value
125+
}
126+
127+
//类型化的foreach遍历
128+
foreach (JsonKeyValuePair item in json.XXArrayProperty)
129+
{
130+
//item.Key
131+
//item.Value
132+
}
133+
112134
//显式赋值类型
113135
IEnumerable<KeyValuePair<string, dynamic?>> enumerable = json;
136+
114137
//通过IDynamicKeyValueEnumerable
115138
var enumerable = ((IDynamicKeyValueEnumerable)json).AsEnumerable();
116139
```

src/Cuture.Extensions.SystemTextJson.Dynamic/Cuture.Extensions.SystemTextJson.Dynamic.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939

4040
<Authors>Stratos</Authors>
4141

42-
<Version>1.1.3</Version>
42+
<Version>1.1.4</Version>
4343

4444
<PackageLicenseExpression>MIT</PackageLicenseExpression>
4545
<PackageProjectUrl>https://github.com/cuture/Cuture.Extensions.SystemTextJson.Dynamic</PackageProjectUrl>

src/Cuture.Extensions.SystemTextJson.Dynamic/JsonDynamicAccessor.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.Dynamic;
1+
using System.Collections;
2+
using System.Dynamic;
23
using System.Text.Json.Nodes;
34

45
namespace System.Text.Json.Dynamic;
@@ -51,6 +52,17 @@ public override bool TryConvert(ConvertBinder binder, out object? result)
5152
{
5253
result = Node;
5354
}
55+
else if (binder.ReturnType == typeof(IEnumerable))
56+
{
57+
if (this is IDynamicEnumerable dynamicEnumerable)
58+
{
59+
result = dynamicEnumerable.AsEnumerable();
60+
}
61+
else if (this is IDynamicKeyValueEnumerable localDynamicKeyValueEnumerable)
62+
{
63+
result = localDynamicKeyValueEnumerable.AsEnumerable();
64+
}
65+
}
5466
else
5567
{
5668
result = Node.Deserialize(binder.ReturnType, JSON.s_defaultJsonSerializerOptions);
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#pragma warning disable IDE0079
2+
#pragma warning disable IDE0130
3+
#pragma warning disable IDE0161
4+
5+
#if NETSTANDARD2_0
6+
7+
namespace System.Runtime.CompilerServices
8+
{
9+
internal class IsExternalInit
10+
{
11+
}
12+
}
13+
14+
#endif
15+
16+
namespace System.Text.Json.Dynamic
17+
{
18+
/// <summary>
19+
/// Json字段的Key - Value结构
20+
/// </summary>
21+
/// <param name="Key">key</param>
22+
/// <param name="Value">值</param>
23+
public readonly record struct JsonKeyValuePair(string Key, dynamic? Value)
24+
{
25+
/// <summary>
26+
/// 隐式转换
27+
/// </summary>
28+
/// <param name="value"></param>
29+
public static implicit operator JsonKeyValuePair(KeyValuePair<string, dynamic?> value)
30+
{
31+
return new(value.Key, value.Value);
32+
}
33+
34+
/// <summary>
35+
/// 隐式转换
36+
/// </summary>
37+
/// <param name="value"></param>
38+
public static implicit operator KeyValuePair<string, object?>(JsonKeyValuePair value)
39+
{
40+
return new(value.Key, value.Value as object);
41+
}
42+
}
43+
}

test/Cuture.Extensions.SystemTextJson.Dynamic.Test/DynamicEnumerableTest.cs

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,31 @@ public class DynamicEnumerableTest
55
{
66
#region Public 方法
77

8+
[TestMethod]
9+
public void Should_Array_EqualOrigin()
10+
{
11+
DynamicJSONTestClass.GetTestValue(out var origin, out var json);
12+
13+
var index = 0;
14+
foreach (var item in json.MyProperty6)
15+
{
16+
Check(origin.MyProperty6[index++], item);
17+
}
18+
19+
index = 0;
20+
21+
foreach (dynamic item in json.MyProperty7)
22+
{
23+
Check(origin.MyProperty7[index++], item);
24+
}
25+
26+
static void Check(object originValue, dynamic value)
27+
{
28+
//直接比较有点麻烦。。直接转json字符串比较
29+
Assert.AreEqual(JsonSerializer.Serialize(originValue), JSON.stringify(value));
30+
}
31+
}
32+
833
[TestMethod]
934
public void ShouldCastFail()
1035
{
@@ -90,7 +115,7 @@ public void ShouldEqualLinqOnOrigin()
90115
var filtered = origin.MyProperty6.Where(m => m[0] > '1').ToArray();
91116
var dynamicFiltered = enumerable.Where(m => m[0] > '1').ToArray();
92117

93-
Assert.AreEqual(filtered.Length, dynamicFiltered.Length);
118+
Assert.HasCount(filtered.Length, dynamicFiltered);
94119

95120
for (int i = 0; i < filtered.Length; i++)
96121
{
@@ -107,7 +132,7 @@ public void ShouldEqualOrigin()
107132

108133
var dynamicToArray = enumerable.ToArray();
109134

110-
Assert.AreEqual(origin.MyProperty6.Length, dynamicToArray.Length);
135+
Assert.HasCount(origin.MyProperty6.Length, dynamicToArray);
111136

112137
for (int i = 0; i < origin.MyProperty6.Length; i++)
113138
{
@@ -130,6 +155,18 @@ public void ShouldEqualOriginProperty()
130155
}
131156
}
132157

158+
//foreach
159+
foreach (var item in json)
160+
{
161+
Check(origin, item.Key, item.Value);
162+
}
163+
164+
//typed foreach
165+
foreach (JsonKeyValuePair item in json)
166+
{
167+
Check(origin, item.Key, item.Value);
168+
}
169+
133170
//IEnumerable<dynamic>
134171
{
135172
IEnumerable<dynamic> dynamicEnumerable = json;

0 commit comments

Comments
 (0)