JArray 内容类型的运行时确定
Runtime determination of JArray content types
我必须在运行时确定要在相应方法中使用的 JSON 的 JArray
对象的类型:
我的部分 JSON 看起来像:
{
"$type": "System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[System.Object, mscorlib]], mscorlib",
"listdouble": {
"$type": "System.Collections.Generic.List`1[[System.Double, mscorlib]], mscorlib",
"$values": [
1,
3
]
},
"listbool": {
"$type": "System.Collections.Generic.List`1[[System.Boolean, mscorlib]], mscorlib",
"$values": [
true,
false
]
},
"liststring": {
"$type": "System.Collections.Generic.List`1[[System.String, mscorlib]], mscorlib",
"$values": [
null,
" ",
"New String"
]
}
}
这是从 Dictionay<string, object>
连载的 Json 的一部分。在运行时,它被反序列化为一个字典,键映射到 JArrays
。一旦我知道其中包含的数据类型,我就可以在 JArray
上使用 ToObject
方法,但是如何确定它是由什么类型组成的呢?比如字典键是映射到 List<double>
还是 List<bool>
?
我会做的是使用动态对象反序列化 JSON like
dynamic d = JsonConvert.DeserializeObject(jsonString);
然后通过
访问数组
JArray arrayOfDoubles = d.listdouble.values;
并检查包含的类型
List<JTokenType> listOfTypes = arrayOfDoubles.GroupBy(item => item.Type).Select(item => item.Key).ToList();
在这种情况下,listOfTypes 的输出是
[0] Integer
但你当然可以从中得到一个双精度数组。
List<double> listOfDoubles = arrayOfDoubles.ToObject<List<double>>();
结果就好了:
[0] 1.0
[1] 3.0
与您的布尔列表相同:
JArray arrayOfBools = d.listbool.values;
listOfTypes = arrayOfBools.GroupBy(item => item.Type).Select(item => item.Key).ToList();
listOfTypes 的输出
[0] Boolean
反序列化:
List<bool> listOfBools = a.ToObject<List<bool>>();
输出:
[0] true
[1] true
同样适用于字符串。
您还可以通过
从您提供的类型反序列化您的数组
var type = d.listdouble.type; // "System.Collections.Generic.List`1[[System.Double, mscorlib]], mscorlib"
var myType = Type.GetType(type.ToString()); // get the type out of it
var myGenericList = arrayOfDoubles.ToObject(myType);
myGenericList
的类型为 {System.Collections.Generic.List<double>}
,值为 [1.0, 3.0]。工作正常。
因此您可以根据 json 数组中的元素检查 json 类型 d.listdouble.type
以确保它会被反序列化。
希望对您有所帮助!
我必须在运行时确定要在相应方法中使用的 JSON 的 JArray
对象的类型:
我的部分 JSON 看起来像:
{
"$type": "System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[System.Object, mscorlib]], mscorlib",
"listdouble": {
"$type": "System.Collections.Generic.List`1[[System.Double, mscorlib]], mscorlib",
"$values": [
1,
3
]
},
"listbool": {
"$type": "System.Collections.Generic.List`1[[System.Boolean, mscorlib]], mscorlib",
"$values": [
true,
false
]
},
"liststring": {
"$type": "System.Collections.Generic.List`1[[System.String, mscorlib]], mscorlib",
"$values": [
null,
" ",
"New String"
]
}
}
这是从 Dictionay<string, object>
连载的 Json 的一部分。在运行时,它被反序列化为一个字典,键映射到 JArrays
。一旦我知道其中包含的数据类型,我就可以在 JArray
上使用 ToObject
方法,但是如何确定它是由什么类型组成的呢?比如字典键是映射到 List<double>
还是 List<bool>
?
我会做的是使用动态对象反序列化 JSON like
dynamic d = JsonConvert.DeserializeObject(jsonString);
然后通过
访问数组JArray arrayOfDoubles = d.listdouble.values;
并检查包含的类型
List<JTokenType> listOfTypes = arrayOfDoubles.GroupBy(item => item.Type).Select(item => item.Key).ToList();
在这种情况下,listOfTypes 的输出是
[0] Integer
但你当然可以从中得到一个双精度数组。
List<double> listOfDoubles = arrayOfDoubles.ToObject<List<double>>();
结果就好了:
[0] 1.0
[1] 3.0
与您的布尔列表相同:
JArray arrayOfBools = d.listbool.values;
listOfTypes = arrayOfBools.GroupBy(item => item.Type).Select(item => item.Key).ToList();
listOfTypes 的输出
[0] Boolean
反序列化:
List<bool> listOfBools = a.ToObject<List<bool>>();
输出:
[0] true
[1] true
同样适用于字符串。
您还可以通过
从您提供的类型反序列化您的数组var type = d.listdouble.type; // "System.Collections.Generic.List`1[[System.Double, mscorlib]], mscorlib"
var myType = Type.GetType(type.ToString()); // get the type out of it
var myGenericList = arrayOfDoubles.ToObject(myType);
myGenericList
的类型为 {System.Collections.Generic.List<double>}
,值为 [1.0, 3.0]。工作正常。
因此您可以根据 json 数组中的元素检查 json 类型 d.listdouble.type
以确保它会被反序列化。
希望对您有所帮助!