YamlDotNet:如何自定义反序列化器以处理具有不同类型值的相同键

标签 yaml yamldotnet

config.yaml:

App1:
  settings:
    redirectUrl: http://www.test.com
App2:
  settings:
    redirectUrl:
      test: http://www.test.com
      prod: http://www.prod.com

C# 对象

public class Config
 {
    public Dictionary<string, App> Apps { get; set; }
 }

public class App
 {
    public Dictionary<string, Setting> Settings { get; set; }
 }

public class Setting
 {
    public string Test {get;set;}
    public string Prod {get;set;}
 }

预期结果:

对于App1testprod都是相同的http://www.test.com

对于 App2testhttp://www.test.comprodhttp://www.prod.com

我做了很多研究,但不知道如何通过使用自定义反序列化器来实现这一点。 请帮忙..

最佳答案

您可以使您的 Settings 类实现 IYamlConvertible。该接口(interface)允许您控制序列化过程。一个可能的实现可能是:

public class SettingsBase
{
    public string Test { get; set; }
    public string Prod { get; set; }
}

public class Setting : SettingsBase, IYamlConvertible
{
    public void Read(IParser parser, Type type, ObjectDeserializer nestedObjectDeserializer)
    {
        var scalar = parser.Allow<Scalar>();
        if (scalar != null)
        {
            Test = Prod = scalar.Value;
        }
        else
        {
            var values = (SettingsBase)nestedObjectDeserializer(typeof(SettingsBase));
            this.Test = values.Test;
            this.Prod = values.Prod;
        }
    }
    
    public void Write(IEmitter emitter, ObjectSerializer nestedObjectSerializer)
    {
        if (Test == Prod)
        {
            nestedObjectSerializer(Test);
        }
        else
        {
            nestedObjectSerializer(new SettingsBase { Test = this.Test, Prod = this.Prod });
        }
    }
}

这里,我使用基类 (SettingsBase) 作为一种轻松(反)序列化属性的方法,但也可以使用另一种策略。基本上,Read 方法检查当前标记是否是标量。如果是这样,它就使用它的值。否则,它会反序列化为 SettingsBaseWrite 方法执行相反的操作。

A fully working example is available here

关于YamlDotNet:如何自定义反序列化器以处理具有不同类型值的相同键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51435425/

相关文章:

java - 如何使用java将yaml文件转换为数组

go - 如何在保留注释的情况下解析 golang 中的一般 yaml?

javascript - 通过 Patch 方法更新 Yaml 文件不起作用

ruby - 从 YAML 配置文件中获取键名

c# - 如何将不匹配的标签序列化到字典?

c# - 在 C# 中合并 YAML

yaml - 向测试厨房添加属性

yamldotnet - 使用 |? 序列化多行字符串

c# - 如何使用 DeserializerBuilder?

c# - 如何在C#中删除Yaml文件末尾的3个点?