C# Newtonsoft两次反序列化同一json流的有效方法

C# Newtonsoft两次反序列化同一json流的有效方法,c#,json.net,C#,Json.net,我在System.IO.StreamReader中收到了一个json。其结构如下: { "data": [ { "Property1": "Value1", "Property2": "Value2" }, { "Property1": "Value3", "Property2": "Value4" } ], "m

我在System.IO.StreamReader中收到了一个json。其结构如下:

{
    "data": [
        {
            "Property1": "Value1",
            "Property2": "Value2"
        },
        {
            "Property1": "Value3",
            "Property2": "Value4"
        }
    ],
    "metaData": {
        (some other structure)
    }
}
我有两个类,一个是Property1作为数据字段,另一个是Property2作为数据字段

我想使用传入流将这个json反序列化为我拥有的两个类的两个独立集合

到目前为止,我只通过先对流进行字符串化,然后调用两次DeserliazeObjectstring来做到这一点。但随后大量内存被不必要地分配

如何通过对DeserializeObjectstreamReader的单个调用来实现这一点?Newtonsoft是否公开任何可以帮助我完成此操作的序列化设置

这是我的代码,效率很低,因为我在调用反序列化程序之前将流转换为字符串:

var responseContent=await response.Content.ReadAsStringAsync; var jObject=jObject.ParseresponseContent; var records=GetRecordsjObject; 私有IList GetRecordsObject作业对象 { 返回作业对象[数据] 儿童 。选择CreateRecord 托利斯特先生; } 私有类1,类2 CreateRecordJToken recordToken { var object1=recordToken.ToObject; var object2=recordToken.ToObject; 返回object1、object2; }
我提供了3条路径,从效率最低的路径开始,但代码最少

直接从流反序列化到JObject中

这样可以避免先将整个数据转换为字符串。这样可以节省字符串的内存空间

var serializer = new JsonSerializer();
using (var textReader = new StreamReader(stream))
using (var jsonReader = new JsonTextReader(textReader))
{
    var jobject = (JObject)serializer.Deserialize(jsonReader);
}
反序列化为C类,然后创建所需的类。JObject比POCO更重,消耗更多内存

这是直截了当的。假设您创建的类是数据

使用JsonTextReader直接读取目标数据结构

这涉及到手动将json流的属性和值读取到所需的结构中。它可以节省任何中间对象的内存空间,或者更确切地说,任何中间对象将只包含您正在读取的当前标记,而不是整个数据。如果返回IEnumerable,则方法的用户实际上可以以流式方式处理结果,从而使其成为一种算法


我将让您在文档中挖掘如何使用它:

为什么不在反序列化一次后复制集合?您可以共享类结构和为反序列化编写的代码吗?创建一个同时具有这两个属性的类型或使用动态类型,反序列化到该类型,然后使用LINQ创建您需要的类型。@Sinatr似乎OP知道DeserializeObjectStreamReader,因为他们在最后一段中提到它是一个理想的用例。他们使用字符串只是因为这是他们知道的重用数据的唯一方法。在不知道如何在单独的读取操作中保持流的打开状态的情况下,我可以看到问题所在。您可以从StreamReader创建JsonTextReader。谢谢。我不知道JsonTextReader,但当我查看它时,我决定我不走这条乏味的道路。我太老了,不适合这样做:我可能会选择选项2,这也是其他人在评论中提出的。但你的回答让我放心,我没有错过更好的解决方案。
var serializer = new JsonSerializer();
using (var textReader = new StreamReader(stream))
using (var jsonReader = new JsonTextReader(textReader))
{
    var data = serializer.Deserialize<Data>(jsonReader);
}