C# 堆栈的反序列化<&燃气轮机;

C# 堆栈的反序列化<&燃气轮机;,c#,serialization,json.net,C#,Serialization,Json.net,我正在尝试反序列化一个对象,该对象包含类型为Stack的属性: 公共类卡 { 公共字符串名称{get;set;} } 公开课游戏 { 公共堆栈卡{get;}=new Stack(); } var game=新游戏(); game.Cards.Push(新卡(){Name=“Whatever”}); 字符串ser=JsonConvert.SerializeObject(游戏); Game unser=JsonConvert.DeserializeObject(ser); 当我尝试反序列化以前序列

我正在尝试反序列化一个对象,该对象包含类型为
Stack
的属性:

公共类卡
{
公共字符串名称{get;set;}
}
公开课游戏
{
公共堆栈卡{get;}=new Stack();
}
var game=新游戏();
game.Cards.Push(新卡(){Name=“Whatever”});
字符串ser=JsonConvert.SerializeObject(游戏);
Game unser=JsonConvert.DeserializeObject(ser);
当我尝试反序列化以前序列化的对象时,Cards属性包含一个空的堆栈

缺少二传手不是问题所在。当我将
堆栈
更改为
列表
反序列化工作时:

public class Game 
{
    public List<Card> Cards { get; } = new List<Card>();
}
var game = new Game();
game.Cards.Add(new Card() { Name = "Whatever"));
string ser = JsonConvert.SerializeObject(game);
Game unser = JsonConvert.DeserializeObject<Game>(ser);
公共类游戏
{
公共列表卡{get;}=new List();
}
var game=新游戏();
game.Cards.Add(新卡(){Name=“Whatever”);
字符串ser=JsonConvert.SerializeObject(游戏);
Game unser=JsonConvert.DeserializeObject(ser);
因此,在使用
列表
,而不是
堆栈

因此,我的问题是:

  • 为什么:)
  • 我是否可以强制Json.NET使用
    堆栈

  • 正如dbc已经显示的,这不是重复。问题不是条目的方向错误,而是条目完全丢失。

    使用Json.NET反序列化
    堆栈有一个已知问题,这在中进行了解释

    报告的行为是,
    Stack
    在反序列化时反转,建议的解决方案是使用自定义的
    JsonConverter
    ,如图所示

    不幸的是,解决方案似乎不适用于像您这样的get only堆栈属性。即使我为
    stack
    指定了一个工作转换器,get only属性返回为空。有关此问题的演示,请参阅

    那么,为什么会发生这种情况呢?因为实现了
    IEnumerable
    而不是
    ICollection
    ,所以将
    Stack
    解释为必须通过its构造的只读集合。然后,在尝试反序列化get only、预分配的
    Stack
    属性时,决定不能使用预先存在的值已使用(因为它是只读集合)和新分配的集合无法回退(因为属性不可写)JSON属性必须跳过。当然,这并不能说明
    JsonConverter
    如果存在可能会以某种方式填充集合,即使JSON.NET不能

    这对我来说就像一个bug;您可能会对Newtonsoft说,即使使用自定义的
    JsonConverter
    ,也无法反序列化get only
    堆栈
    属性

    作为一种保留
    堆栈
    属性不变性的解决方法,除了为
    堆栈
    创建自定义的
    JsonConverter
    ,您还可以为
    游戏
    创建一个参数化构造函数,该构造函数接受
    堆栈卡
    参数,并用以下标记:

    其中,
    StackConverter
    逐字取自


    演示显示解决方法确实有效。

    使用Json.NET反序列化
    堆栈时存在一个已知问题,如中所述

    报告的行为是,
    Stack
    在反序列化时反转,建议的解决方案是使用自定义的
    JsonConverter
    ,如图所示

    不幸的是,解决方案似乎不适用于像您这样的get only堆栈属性。即使我为
    stack
    指定了一个工作转换器,get only属性返回为空。有关此问题的演示,请参阅

    那么,为什么会发生这种情况呢?因为实现了
    IEnumerable
    而不是
    ICollection
    ,所以将
    Stack
    解释为必须通过its构造的只读集合。然后,在尝试反序列化get only、预分配的
    Stack
    属性时,决定不能使用预先存在的值已使用(因为它是只读集合)和新分配的集合无法回退(因为属性不可写)JSON属性必须跳过。当然,这并不能说明
    JsonConverter
    如果存在可能会以某种方式填充集合,即使JSON.NET不能

    这对我来说就像一个bug;您可能会对Newtonsoft说,即使使用自定义的
    JsonConverter
    ,也无法反序列化get only
    堆栈
    属性

    作为一种保留
    堆栈
    属性不变性的解决方法,除了为
    堆栈
    创建自定义的
    JsonConverter
    ,您还可以为
    游戏
    创建一个参数化构造函数,该构造函数接受
    堆栈卡
    参数,并用以下标记:

    其中,
    StackConverter
    逐字取自


    演示该解决方法是否有效。

    此代码是否编译?属性定义中有两种类型<代码>字符串堆栈卡{get;}
    。它是字符串还是堆栈?抱歉。键入错误。已更正相关(但可能不是完美的副本,需要检查):…好的,我认为
    StackConverter
    from应该适合您,因为它使用了现有的值(如果存在)。可能存在@OleAlbers的重复-实际上还有一个额外的问题。将很快编写一些内容。此代码是否编译?您的属性定义中有两种类型
    字符串堆栈卡{get;}
    。它是字符串还是堆栈?抱歉。打字错误。更正相关(但可能不是完美的副本,需要检查):…好的,我认为
    StackConverter
    from应该适合您,因为它使用现有值(如果存在)。可能重复@OleAlbers-实际上还有一个额外的问题。将编写一些详细信息
    public class Game 
    {
        public List<Card> Cards { get; } = new List<Card>();
    }
    var game = new Game();
    game.Cards.Add(new Card() { Name = "Whatever"));
    string ser = JsonConvert.SerializeObject(game);
    Game unser = JsonConvert.DeserializeObject<Game>(ser);
    
    public class Game 
    {
        public Game() { this.cards =  new Stack<Card>(); }
    
        [JsonConstructor]       
        Game(Stack<Card> cards)
        {
            this.cards = cards ??  new Stack<Card>();
        }
    
        readonly Stack<Card> cards;
    
        public Stack<Card> Cards { get { return cards; } }
    }
    
    var settings = new JsonSerializerSettings
    {
        Converters = { new StackConverter() },
    };          
    var unser = JsonConvert.DeserializeObject<Game>(ser, settings);