我有一个树结构,其中节点有子指针和父指针。我有一些问题让它很好地序列化(这将用于配置,因此它需要对操作/配置管理器有些可读),并且在尝试了序列化约定和属性的不同组合后,我仍然卡住了。
我的类型如下:
public class NestedConfigurationTree<T> where T : class
{
public InternalNode<T> _root { get; set; }
public class InternalNode<TValue> where TValue : class
{
public Dictionary<string, InternalNode<TValue>> _children { get; set; }
public InternalNode<TValue> _parent { get; set; }
public TValue _value { get; set; }
}
}
当我允许循环引用([JsonObject(IsReference = true)]
)时,每个节点都获得如下所示的JSON:
"$id": "3",
"_children": {
"ConfigurationItem": {
"$id": "4",
"_children": {},
"_parent": {
"$ref": "3"
},
"_value": "Some value"
}
},
这显然让最终用户感到困惑,他们不想要$ id和_parent的东西。由于父文件在文档结构中非常明显,我可以避免序列化它并在加载时以某种方式重新创建吗?
此外,是否可以避免拥有公共财产?我最初将其写为private readonly
字段,但这使得序列化程序忽略了所有字段。
答案 0 :(得分:0)
并非所有内容都适合直接存储在数据库中。您已经展示了这种情景的一个很好的例子。如果您的最终用户会对此感到困惑,那么您想要针对它的任何疑问也会如此。
我的建议是拥有一个没有这些引用的树版本。序列化,看起来像这样:
{
"Value" : "A",
"Children" : [
{
"Value" : "B",
"Children" : [
{
"Value" : "C",
"Children" : [
{
"Value" : "D",
}
]
},
{
"Value" : "E",
"Children" : [
{
"Value" : "F",
"Children" : []
},
{
"Value" : "G",
"Children" : []
}
]
}
]
}
]
}
序列化时,您只需忽略父/子链接,在反序列化时,您可以将它们连接起来。
而不是第二组类,您可以在自定义JsonConverter
中完成所有操作 - 这使您可以对如何序列化或反序列化任何特定实体进行细粒度控制。
另一种选择(也许是最简单的)是使用方法而不是遍历链接的属性。换句话说,而不是:
Node Parent { get; }
IEnumerable<Node> Children { get; }
你会使用:
Node GetParent();
IEnumerable<Node> GetChildren();
序列化过程中不会遵循方法,因此这是最容易做到的事情。