将YAML反序列化为自定义类型
本文关键字:自定义 类型 反序列化 YAML | 更新日期: 2023-09-27 17:59:09
我目前正在尝试使用YamlDotNet库将YAML文档反序列化为标准.NET对象,例如用于标量值的string
和用于映射的Dictionary<string, object>
。
我想Deserializer
类是最好的选择,但它的输出是object
和Dictionary<object>
。我试着像这样实现自定义INodeTypeResolver
:
class MyNodeTypeResolver : INodeTypeResolver
{
bool INodeTypeResolver.Resolve(NodeEvent nodeEvent, ref Type currentType)
{
if (currentType == typeof(object))
{
if (nodeEvent is SequenceStart)
currentType = typeof(List<object>);
else if (nodeEvent is MappingStart)
currentType = typeof(Dictionary<string, object>);
else if (nodeEvent is Scalar)
currentType = typeof(string);
return true;
}
return false;
}
}
并像这样使用它:
Deserializer deserializer = new Deserializer();
deserializer.TypeResolvers.Add(new MyNodeTypeResolver());
var res = deserializer.Deserialize(input);
但这似乎没有任何效果。有什么方法可以更改Deserializer
生成的对象的类型吗?
使用INodeTypeResolver
是正确的,但您需要构建并使用自定义反序列化程序:
DeserializerBuilder deserializerBuilder = new DeserializerBuilder()
.WithNodeTypeResolver(new MyNodeTypeResolver());
IDeserializer deserializer = deserializerBuilder.Build();
var res = deserializer.Deserialize(input);
AFAIK,Deserialize采用类型参数,这真的很好
%YAML 1.1
%TAG !namespace! _MyNamespace.NestedClass.Whatever.
---
entry_0: !namespace!MyMessage
format: Alert
desc: "Entry One! Uses the exact string representation of the desired type. (A bit fragile, IMHO)"
entry_1: !!message
format: Default
desc: "Entry Two! Uses a type registered beforehand."
entry_2:
format: Default
desc: "Entry Three! Just winging it, sometimes YamlDotNet is exceedingly clever."
...
可以通过反序列化
var dict = new Deserializer().Deserialize<Dictionary<string,MyMessage>>(
new StringReader(that_doc_up_there));
前提是MyMessage具有format和desc属性,并且不在命名空间中。如果是,你可以事先在反序列化程序中注册它,或者为它创建一个新的标记。%tag别名似乎吃掉了标记的第一个字符,所以我加了一个下划线。也许是个虫子。另一种方法是注册,
deserializer.RegisterTagMapping(
"tag:yaml.org,2002:message", typeof(MyMessage));