JsonConvert.Deserializer索引问题在C#中使用Stack集合时遇到了如下问题。确切地说,我不确定为什么会这样。请详细说明解决方案的原因和备选方案。问题-具有Stack作为属性的类。例如,将类命名为Progress。T是Item类型。现在,每当用户取得任何进展时,我们都会将其存储在堆栈中。如果用户介于两者之间,那么下次我们将从堆栈中查看项目,以便我们可以从那个阶段开始。下面的代码片段将介绍正确在尝试的内容……usingstaticSystem.Console;使用System.Collections.Generic;使用Newtonsoft.Json;namespaceStackCollection{classProgram{staticvoidMain(string[]args){Progressprogress=newProgress();progress.Items.Push(newItem{PlanID=null,PlanName="PlanA"});varjsonString=JsonConvert.SerializeObject(进度);vartemp=JsonConvert.DeserializeObject(jsonString);temp.Items.Push(newItem{PlanID=null,PlanName="PlanB"});jsonString=JsonConvert.SerializeObject(temp);temp=JsonConvert.DeserializeObject(jsonString);temp.Items.Push(newItem{PlanID=null,PlanName="PlanC"});jsonString=JsonConvert.SerializeObject(temp);temp=JsonConvert.DeserializeObject(jsonString);WriteLine(temp.Items.Peek().PlanName);读线();}}classProgress{publicStackItems{get;放;}publicProgress(){Items=newStack();}}classItem{publicstringPlanID{get;放;}公共字符串PlanName{得到;放;现在行-WriteLine(temp.Items.Peek().PlanName);应该返回C计划。但它正在返回B计划所以,为什么索引被更改,任何线索或指针都会在那里从帮助看起来Stack被序列化为List。问题是在解构堆栈时这不会保留正确的顺序(项目实际上是按相反的顺序推送的)。以下是此问题的快速解决方法:usingSystem;使用静态System.Console;使用System.Collections.Generic;使用System.Linq;使用System.Runtime.Serialization;使用Newtonsoft.Json;namespaceStackCollection{classProgram{staticvoidMain(string[]args){Progressprogress=newProgress();progress.Items.Push(newItem{PlanID=null,PlanName="PlanA"});varjsonString=JsonConvert.SerializeObject(进度);vartemp=JsonConvert.DeserializeObject(jsonString);temp.Items.Push(newItem{PlanID=null,PlanName="PlanB"});jsonString=JsonConvert.SerializeObject(temp);temp=JsonConvert.DeserializeObject(jsonString);temp.Items.Push(newItem{PlanID=null,PlanName="PlanC"});jsonString=JsonConvert.SerializeObject(temp);temp=JsonConvert.DeserializeObject(jsonString);WriteLine(temp.Items.Peek().PlanName);读线();}}classProgress{[JsonIgnore]publicStackItems{get;放;}publicListItemList{get;放;}[OnSerializing]internalvoidOnSerializing(StreamingContextcontext){ItemList=Items?.ToList();}[OnDeserialized]internalvoidOnDeserialized(StreamingContextcontext){ItemList?.Reverse();Items=newStack(ItemList??Enumerable.Empty());}publicProgress(){Items=newStack();}}classItem{publicstringPlanID{get;放;}publicstringPlanName{get;放;由于Json.NETBehavior知道这一点,如本答案中所述,当反序列化以正确顺序推送项目的堆栈时,您可以使用自定义JsonConverter以下使用转换工具可与Stack使用于何T://////任何Stack的转换器,防止Json.NET在反序列化时反转其顺序。///publicclassStackConverter:JsonConverter{//防止Json.NET在反序列化时颠倒Stack的顺序。//https://github.com/JamesNK/Newtonsoft.Json/issues/971staticTypeStackParameterType(TypeobjectType){while(objectType!=null){if(objectType.IsGenericType){vargenericType=objectType.GetGenericTypeDefinition();如果(genericType==typeof(Stack))返回objectType.GetGenericArguments()[0];}objectType=objectType.BaseType;}返回空值;}publicoverrideboolCanConvert(TypeobjectType){returnStackParameterType(objectType)!=null;}objectReadJsonGeneric(JsonReaderreader,TypeobjectType,objectexistingValue,JsonSerializerserializer){if(reader.TokenType==JsonToken.Null)返回null;varlist=serializer.Deserialize>(reader);varstack=existingValueasStack??(堆)serializer.ContractResolver.ResolveContract(objectType).DefaultCreator();对于(inti=list.Count-1;i>=0;i--)stack.Push(list[i]);返回堆栈;}publicoverrideobjectReadJson(JsonReaderreader,TypeobjectType,objectexistingValue,JsonSerializerserializer){if(reader.TokenType==JsonToken.Null)returnnull;尝试{varparameterType=StackParameterType(objectType);varmethod=GetType().GetMethod("ReadJsonGeneric",BindingFlags.NonPublic|BindingFlags.Instance|BindingFlags.Public);vargenericMethod=method.MakeGenericMethod(new[]{parameterType});返回genericMethod.Invoke(this,newobject[]{reader,objectType,existingValue,serializer});}catch(TargetInvocationExceptionex){//在JsonSerializerException中包装TargetInvocationExceptionthrownewJsonSerializationException("Failedtodeserialize"+objectType,ex);}}publicoverrideboolCanWrite{get{returnfalse;}}公共覆盖voidWriteJson(JsonWriterwriter,objectvalue,JsonSerializerserializer){thrownewNotImplementedException();然后将其添加到JsonSerializerSettings以在反序列化时更正堆栈的顺序:varsettings=newJsonSerializerSettings{Converters=new[]{newStackConverter()}};varjsonString=JsonConvert.SerializeObject(进度,设置);vartemp=JsonConvert.DeserializeObject(jsonString,settings);或者直接使用[JsonConverter(typeof(StackConverter))]标记Stack属性:classProgress{[JsonConverter(typeof(StackConverter))]publicStackItems{get;放;}publicProgress(){Items=newStack();如果您尝试对此进行调试,那么您会注意到在Stack反序列化a之后项目的顺序被破坏了。几个月前,JSON.NETGitHub问题跟踪器上提出了同样的问题。JamesNK的回答:我担心这是Stack的限制。结果在序列化时返回,在反序列化时以相反的顺序返回。以上就是C#学习教程:JsonConvert.Deserializer索引问题分享的全部内容。如果对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右边联系管理员删除。如需转载请注明出处:
