C# 无参数构造函数的自引用类层次结构的序列化/反序列化
我有一个分层类C# 无参数构造函数的自引用类层次结构的序列化/反序列化,c#,json,json.net,deserialization,hierarchy,C#,Json,Json.net,Deserialization,Hierarchy,我有一个分层类ConversationModel,需要序列化/反序列化到JSON 请注意,ConversationNode类没有无参数构造函数。唯一的非默认构造函数也标记为内部。所有类属性都是get only。这是为了使类保持不变、无状态和防白痴 using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using Newtonsoft.Json; public class Co
ConversationModel
,需要序列化/反序列化到JSON
请注意,ConversationNode
类没有无参数构造函数。唯一的非默认
构造函数也标记为内部
。所有类属性都是get only
。这是为了使类保持不变、无状态和防白痴
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using Newtonsoft.Json;
public class ConversationModel
{
public ConversationNode Node { get; }
public ConversationModel ()
=> this.Node = new ConversationNode(this, null);
public static JsonSerializerSettings JsonSerializerSettings
=> new JsonSerializerSettings
{
Formatting = Formatting.Indented,
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
PreserveReferencesHandling = PreserveReferencesHandling.All,
TypeNameAssemblyFormatHandling = TypeNameAssemblyFormatHandling.Full,
Converters = new [] { new ConversationModelJsonConverter(), },
};
public string Serialize ()
=> JsonConvert.SerializeObject(this, this.GetType(), ConversationModel.JsonSerializerSettings);
public static ConversationModel FromJson (string json)
=> JsonConvert.DeserializeObject<ConversationModel>(json, ConversationModel.JsonSerializerSettings);
}
public class ConversationNode
{
public ConversationModel Model { get; }
public ConversationNode Parent { get; }
public ConversationNodeList Nodes { get; }
internal ConversationNode (ConversationModel model, ConversationNode parent)
{
this.Model = model ?? throw (new ArgumentNullException(nameof(model)));
this.Parent = parent ?? throw (new ArgumentNullException(nameof(parent)));
this.Nodes = new ConversationNodeList (model, parent);
}
}
public class ConversationNodeList:
List<ConversationNode>
{
public ConversationModel Model { get; }
public ConversationNode Parent { get; }
public ConversationNodeList (ConversationModel model, ConversationNode parent)
{
this.Model = model;
this.Parent = parent;
}
}
问题是:
JsonConverter
来实现这一点?如果是,怎么做JsonConverter
更简单的方法“当然,JsonSerializer需要一个公共的、默认的、无参数的构造函数”——事实并非如此。它可以使用非公共构造函数,也可以使用非无参数构造函数(就像您当前拥有的构造函数)。我用
[jsonstructor]
属性标记了内部
构造函数,它抛出了一个JsonSerializationException
,尽管是在层次结构的某个地方。换句话说,它可以调用构造函数,但在某些情况下会失败。反序列化的JSON是使用具有相同设置的相同序列化程序生成的。奇怪。我认为您需要提供可复制的示例,因为使用当前代码,可以按原样序列化和反序列化basicnew ConversationModel()
,而无需修改(更改ConversationNode
以允许空父级除外).PreserveReferencesHandling
被记录为不使用非默认构造函数。请参阅:以及:当通过非默认构造函数设置值时,无法保留引用。对于非默认构造函数,必须在父值之前创建子值,以便将其传递到构造函数中,从而无法跟踪引用。也就是说,Json.NET通常支持参数化构造函数。有关选择适当构造函数的算法,请参见。
public sealed class ConversationModelJsonConverter:
JsonConverter<ConversationModel>
{
public override void WriteJson (JsonWriter writer, [AllowNull] ConversationModel value, JsonSerializer serializer)
{
// ???
}
public override ConversationModel ReadJson (JsonReader reader, Type objectType, [AllowNull] ConversationModel existingValue, bool hasExistingValue, JsonSerializer serializer)
{
// ???
return (null);
}
}