使用 Yaml IEnumerable class 序列化导致奇怪的输出
Serializing with Yaml IEnumerable class results in weird output
被反序列化/序列化的类型为(排除部分):
public class Entry : IEnumerable<Entry>{
public string name { get; set; }
public List<Entry> items { get; set; }
public Entry()
{
}
public IEnumerator<Entry> GetEnumerator()
{
yield return this;
if (items != null && items.Count > 0)
{
foreach (var child in items)
{
foreach (var grandChild in child)
yield return grandChild;
}
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
表示没有循环引用的树数据层次结构。
虽然实现了 IEnumerable 接口,但实现了递归遍历当前下的每个子条目,它会导致奇怪的输出(见最后)。
如果删除 IEnumerable 接口,它会正确序列化。
反序列化通常是双向的(从原始数据)。
没有错误或警告。
所以我的问题是,这是一个错误还是我做错了什么。感谢任何见解。
输出(部分):
- &o0
- *o0
- &o1
- *o1
- &o2
- *o2
- &o3
- *o3
- &o4
- *o4
- &o5
- *o5
- &o6
- *o6
- &o7
- *o7
- *o4
- *o5
- *o6
- *o7
- *o3
预期输出(部分):
- name: Runtime
items:
- name: Util
items:
- name: NaturalStringComparer
items:
这是因为实现 IEnumerable<>
的类型被映射到序列,其中可枚举返回的每个元素都被序列化为序列的一项。但是每个元素本身就是一个 IEnumerable<>
这意味着它也将被序列化为一个序列。
此过程最终会多次发出相同的 Entry
。因此,每个 Entry
第一次被序列化时,它被分配一个锚点,下一次序列化程序遇到它时,发出一个别名来引用该条目的初始出现。
我认为您无法改变这种行为,所以我的建议是不要实施 IEnumerable<>
而是使用 属性 来生成所有节点,标记为 [YamlIgnore]
.
被反序列化/序列化的类型为(排除部分):
public class Entry : IEnumerable<Entry>{
public string name { get; set; }
public List<Entry> items { get; set; }
public Entry()
{
}
public IEnumerator<Entry> GetEnumerator()
{
yield return this;
if (items != null && items.Count > 0)
{
foreach (var child in items)
{
foreach (var grandChild in child)
yield return grandChild;
}
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
表示没有循环引用的树数据层次结构。
虽然实现了 IEnumerable 接口,但实现了递归遍历当前下的每个子条目,它会导致奇怪的输出(见最后)。
如果删除 IEnumerable 接口,它会正确序列化。
反序列化通常是双向的(从原始数据)。
没有错误或警告。
所以我的问题是,这是一个错误还是我做错了什么。感谢任何见解。
输出(部分):
- &o0
- *o0
- &o1
- *o1
- &o2
- *o2
- &o3
- *o3
- &o4
- *o4
- &o5
- *o5
- &o6
- *o6
- &o7
- *o7
- *o4
- *o5
- *o6
- *o7
- *o3
预期输出(部分):
- name: Runtime
items:
- name: Util
items:
- name: NaturalStringComparer
items:
这是因为实现 IEnumerable<>
的类型被映射到序列,其中可枚举返回的每个元素都被序列化为序列的一项。但是每个元素本身就是一个 IEnumerable<>
这意味着它也将被序列化为一个序列。
此过程最终会多次发出相同的 Entry
。因此,每个 Entry
第一次被序列化时,它被分配一个锚点,下一次序列化程序遇到它时,发出一个别名来引用该条目的初始出现。
我认为您无法改变这种行为,所以我的建议是不要实施 IEnumerable<>
而是使用 属性 来生成所有节点,标记为 [YamlIgnore]
.