JsonConvert.Deserializer 索引问题

时间:2023-04-26
本文介绍了JsonConvert.Deserializer 索引问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

在 C# 中玩 Stack 集合时,我遇到了以下问题.确切地说,我不确定为什么会这样.请说明原因和解决方案的替代方案.

While playing around Stack collection in C# I encountered the following issue. Exactly I am not sure why it is happening. Please put some light on the reason and alternative to the solution.

问题 -

具有 Stack 作为属性的类.例如,将该类命名为 Progress.T 是类类型 Item.

A class having Stack as property. For example name that class as Progress. T is of class type Item.

现在,每当用户取得任何进展时,我们都会将其存储在堆栈中.如果用户在两者之间离开,那么下次我们将从堆栈中窥视项目,以便从那个阶段开始.下面的代码片段将让您了解正在尝试的内容...

Now whenever the user makes any progress we will be storing in stack. And if user leaves in between, then next time we will peek the item from the stack so from that stage. Below code snippet will give an idea of what is being tried...

using static System.Console;
using System.Collections.Generic;
using Newtonsoft.Json;

namespace StackCollection
{
    class Program
    {
        static void Main(string[] args)
        {
            Progress progress = new Progress();

            progress.Items.Push(new Item { PlanID = null, PlanName = "Plan A" });

            var jsonString = JsonConvert.SerializeObject(progress);
            var temp = JsonConvert.DeserializeObject<Progress>(jsonString);

            temp.Items.Push(new Item { PlanID = null, PlanName = "Plan B" });

            jsonString = JsonConvert.SerializeObject(temp);
            temp = JsonConvert.DeserializeObject<Progress>(jsonString);

            temp.Items.Push(new Item { PlanID = null, PlanName = "Plan C" });

            jsonString = JsonConvert.SerializeObject(temp);
            temp = JsonConvert.DeserializeObject<Progress>(jsonString);

            WriteLine(temp.Items.Peek().PlanName);

            ReadLine();
        }
    }

    class Progress
    {
        public Stack<Item> Items { get; set; }

        public Progress()
        {
            Items = new Stack<Item>();
        }
    }

    class Item
    {
        public string PlanID { get; set; }

        public string PlanName { get; set; }
    }
}

现在该行 -

WriteLine(temp.Items.Peek().PlanName);

应该返回

C计划

但它正在返回

B计划

那么,为什么要更改索引,任何线索或指针都会有所帮助.

So, why the index is being changed, any clue or pointer will be helpful.

推荐答案

好像栈被序列化为一个List.问题是这在解构堆栈时不能保持正确的顺序(项目实际上是按相反的顺序推送的).以下是此问题的快速解决方法:

It seems like the stack is being serialized as a List. The problem is that this does not preserve the proper order when deconstructing the stack (the items are actually pushed in the reverse order). Here's a quick workaround to this issue:

using System;
using static System.Console;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using Newtonsoft.Json;

namespace StackCollection
{
    class Program
    {
        static void Main(string[] args)
        {
            Progress progress = new Progress();

            progress.Items.Push(new Item { PlanID = null, PlanName = "Plan A" });

            var jsonString = JsonConvert.SerializeObject(progress);
            var temp = JsonConvert.DeserializeObject<Progress>(jsonString);

            temp.Items.Push(new Item { PlanID = null, PlanName = "Plan B" });

            jsonString = JsonConvert.SerializeObject(temp);
            temp = JsonConvert.DeserializeObject<Progress>(jsonString);

            temp.Items.Push(new Item { PlanID = null, PlanName = "Plan C" });

            jsonString = JsonConvert.SerializeObject(temp);
            temp = JsonConvert.DeserializeObject<Progress>(jsonString);

            WriteLine(temp.Items.Peek().PlanName);

            ReadLine();
        }
    }

    class Progress
    {
        [JsonIgnore]
        public Stack<Item> Items { get; set; }

        public List<Item> ItemList { get; set; }

        [OnSerializing]
        internal void OnSerializing(StreamingContext context)
        {
            ItemList = Items?.ToList();
        }

        [OnDeserialized]
        internal void OnDeserialized(StreamingContext context)
        {
            ItemList?.Reverse();
            Items = new Stack<Item>(ItemList ?? Enumerable.Empty<Item>());
        }

        public Progress()
        {
            Items = new Stack<Item>();
        }
    }

    class Item
    {
        public string PlanID { get; set; }

        public string PlanName { get; set; }
    }
}

这篇关于JsonConvert.Deserializer 索引问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

上一篇:使用 Json.NET 序列化时如何应用重新映射所有属性名称的一般规则? 下一篇:将异构 JSON 数组反序列化为协变列表&lt;&gt;使用 Json.NET

相关文章