【问题标题】:Deserializing YAML into Custom Types将 YAML 反序列化为自定义类型
【发布时间】:2014-04-20 11:15:10
【问题描述】:

我目前正在尝试使用 YamlDotNet 库将 YAML 文档反序列化为标准 .NET 对象,例如用于标量值的 string 和用于映射的 Dictionary<string, object>

我猜Deserializer 类是最好的选择,但它的输出是objectDictionary<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产生的对象类型吗?

【问题讨论】:

    标签: c# yamldotnet


    【解决方案1】:

    您在 INodeTypeResolver 的正确轨道上,但您需要构建和使用自定义反序列化器:

    DeserializerBuilder deserializerBuilder = new DeserializerBuilder()
        .WithNodeTypeResolver(new MyNodeTypeResolver());
    IDeserializer deserializer = deserializerBuilder.Build();
    var res = deserializer.Deserialize(input);
    

    【讨论】:

      【解决方案2】:

      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));
      

      【讨论】:

        猜你喜欢
        • 2019-02-08
        • 1970-01-01
        • 1970-01-01
        • 2011-11-03
        • 2023-04-01
        • 2020-10-17
        • 1970-01-01
        • 2010-12-20
        • 2016-03-24
        相关资源
        最近更新 更多