【发布时间】:2020-03-20 23:48:51
【问题描述】:
我有一个在 System.IO.StreamReader 中收到的 json。其结构如下:
{
"data": [
{
"Property1": "Value1",
"Property2": "Value2"
},
{
"Property1": "Value3",
"Property2": "Value4"
}
],
"metaData": {
(some other structure)
}
}
我有两个类,一个以Property1 作为数据字段,另一个以Property2 作为数据字段。
我想使用传入流将此 json 反序列化为我拥有的两个类的两个单独集合。
到目前为止,我只能通过首先对流进行字符串化然后调用DeserliazeObject(string) 两次来做到这一点。但是随后不必要地分配了一大块内存。
如何通过对DeserializeObject(streamReader) 的一次调用来做到这一点? Newtonsoft 是否公开任何可以帮助我解决此问题的序列化设置?
这是我的代码,效率低下,因为我在调用反序列化器之前将流转换为字符串:
var responseContent = await response.Content.ReadAsStringAsync();
var jObject = JObject.Parse(responseContent);
var records = GetRecords(jObject);
private IList<(IClass1, IClass2)> GetRecords(JObject jObject)
{
return jObject["data"]
.Children()
.Select(CreateRecord)
.ToList();
}
private (Class1, Class2) CreateRecord(JToken recordToken)
{
var object1 = recordToken.ToObject<IClass1>();
var object2 = recordToken.ToObject<IClass2>();
return (object1, object2);
}
【问题讨论】:
-
反序列化一次后为什么不直接复制集合?
-
你能分享一下你为反序列化编写的类结构和代码吗?
-
创建一个具有这两个属性的类型(或使用动态类型),反序列化,然后使用 LINQ 创建您需要的类型。
-
@Sinatr 看起来 OP 知道
DeserializeObject(StreamReader),因为他们在最后一段中提到它是一个理想的用例。他们使用string只是因为这是他们知道的重用数据的唯一方法。在不知道如何通过单独的读取操作保持流打开的情况下,我可以看到问题。 -
如果您想保留现有代码,可以使用
JToken.Load(JsonReader)。您可以从StreamReader创建一个JsonTextReader。