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);
因此,在使用列表
,而不是堆栈
因此,我的问题是:
堆栈
正如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);