1

我有一个 Planet 类,其中包含一个瓷砖列表。每个图块还具有相邻图块的列表。以某种方式,所有瓷砖都连接(间接)。现在我正在尝试使用 YamlDotNet 对其进行序列化。然而,发生的事情是我得到了一个非常丑陋的嵌套序列化。

一个最小的工作示例:(https://dotnetfiddle.net/sWGKMB

public class Planet {
    public Tile[] tiles {get;set;}
}

public class Tile {
    public string name { get; set; }
    public Tile[] neighbours { get; set; }
}

public class SerializeObjectGraph
{
    public void Main()
    {
        var p = new Planet();

        var a = new Tile();
        var b = new Tile();
        var c = new Tile();

        a.name = "a";
        b.name = "b";
        c.name = "c";

        a.neighbours = new Tile[] {b,c};
        b.neighbours = new Tile[] {a,c};
        c.neighbours = new Tile[] {b,a};

        p.tiles = new Tile[] {a,b,c};

        var serializer = new Serializer();
        serializer.Serialize(Console.Out, p);
    }
}

这将其作为 yaml 文档给出:

tiles:
- &o0
  name: a
  neighbours:
  - &o1
    name: b
    neighbours:
    - *o0
    - &o2
      name: c
      neighbours:
      - *o1
      - *o0
  - *o2
- *o1
- *o2

如您所见,由于所有瓷砖都以某种方式连接(在我的迷你示例中直接),因此行星列表中的第一个瓷砖将为所有瓷砖创建一个巨大的嵌套结构。

是否可以强制 YamlDotNet 使用“邻居”列表中的引用以及图块列表中的实际类?所以它看起来像这样:

tiles:
- &o0
  name: a
  neighbours:
  - *o1
  - *o2
- &o1
  name: b
  neighbours:
  - *o0
  - *o2
- &o2
  name: c
  neighbours:
  - *o0
  - *o1

谢谢!

4

1 回答 1

1

由于 Serializer 的实现方式,不可能实现您想要的。使用的策略是在对象第一次出现在图中时发出对象,并在每隔一次出现时使用引用。

按照你的建议做实际上会产生格式错误的 YAML。该规范明确禁止在声明之前引用节点:

别名节点使用文档中以前未出现的锚是错误的。

一种解决方法是将相邻关系与图块本身分开序列化,但您必须更改对象或使用中间表示。

于 2016-08-31T13:01:14.903 回答