【发布时间】:2020-07-13 17:39:26
【问题描述】:
这是我第一次尝试序列化/反序列化树。除了Path,它工作得很好。它必须从根开始构建,但反序列化从叶子开始。
var root = new Node(null, "rootName");
var tree = new Tree(root);
root.AddChild("childName");
var str = JsonConvert.SerializeObject(tree, Newtonsoft.Json.Formatting.Indented);
var treeRestored = JsonConvert.DeserializeObject<Tree>(str);
...
class Node
{
public IReadOnlyList<Node> Children => _children;
[JsonIgnore]
public string Path { get; } // needs parent
[JsonProperty(ReferenceLoopHandling = ReferenceLoopHandling.Ignore)]
public Node Parent { get; private set; }
public string Name { get; }
public Node(Node parent, string name)
{
Name = name;
Parent = parent;
Path = (parent == null ? "" : (parent.Name + ".")) + name;
_children = new List<Node>();
}
[JsonConstructor]
private Node(string Name, List<Node> Children)
{
this.Name = Name;
_children = Children;
foreach (var child in _children)
{
child.Parent = this;
}
}
public void AddChild(string name)
{
_children.Add(new Node(this, name));
}
private readonly List<Node> _children;
}
class Tree
{
public Node Root;
public Tree(Node root)
{
Root = root;
}
}
所以我尝试了以下方法。我从 Parent 属性中删除了 JsonProperty,更改了序列化命令,并更改了 JSON 构造函数。
var str = JsonConvert.SerializeObject(tree, Newtonsoft.Json.Formatting.Indented,
new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.Objects });
[JsonConstructor]
private Node(string name, Node parent)
{
Name = name;
Parent = parent;
if (Parent != null) // Rebuild path
{
parent._children.Add(this);
Path = parent.Name + "." + Name;
}
else
{
Path = Name;
}
_children = new List<Node>();
}
进行这些更改后,序列化字符串如下所示:
{
"$id": "1",
"Root": {
"$id": "2",
"Children": [
{
"$id": "3",
"Children": [],
"Parent": {
"$ref": "2"
},
"Name": "childName"
}
],
"Parent": null,
"Name": "rootName"
}
}
这个 Json 字符串包含足够的信息来首先创建根,然后是子。但是 JsonConverter 仍然从叶子开始。如何更改订单?
我知道我可以使用OnDeserialized,但这是我最后的选择。
【问题讨论】:
-
好吧,我不明白你的问题是什么,我认为你应该审查并重新表述你的问题,以便更清楚。
-
@Aybe 我想从根目录反序列化树。我提供了一个示例问题。
-
你的意思是你想从 X root 反序列化?如果是这样,那么根本不要使用
Tree类,而是直接序列化你的根节点,这就是我在这里所做的并且它有效。例如JsonConvert.Deserialize<Node>... -
@Aybe 它对我不起作用。也许您可以以我的代码为基础创建实时示例?
标签: c# tree json.net tree-traversal