You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用YamlDotNet动态反序列化可作为标量或序列的Pool字段

解决YamlDotNet中Pool字段多格式反序列化问题

针对你的场景——YAML文件中pool字段既可能是字符串标量,也可能是包含name的对象序列,可通过自定义YAML类型转换器实现动态反序列化,具体步骤如下:

1. 保留原有实体类结构

你的Jobs和Pool类无需大幅修改,保持原定义即可:

public class Jobs
{
    [YamlMember(Alias = "job", ApplyNamingConventions = false, Order = 0)]
    public string Job { get; set; }

    [YamlMember(Alias = "displayName", ApplyNamingConventions = false, Order = 1)]
    public string DisplayName { get; set; }

    [YamlMember(Alias = "pool", ApplyNamingConventions = false, Order = 3)]
    public Pool Pool { get; set; }
}

public class Pool
{
    [YamlMember(Alias = "name", ApplyNamingConventions = false, Order = 0)]
    public string Name { get; set; }
}

2. 添加根实体类(匹配YAML根结构)

由于你的YAML根节点是Jobs数组,需新增一个根类来承接:

public class RootJobConfig
{
    [YamlMember(Alias = "Jobs", ApplyNamingConventions = false)]
    public List<Jobs> JobsList { get; set; }
}

3. 实现自定义类型转换器

创建PoolConverter类实现IYamlTypeConverter接口,处理两种格式的pool字段解析:

using YamlDotNet.Core;
using YamlDotNet.Core.Events;
using YamlDotNet.Serialization;

public class PoolConverter : IYamlTypeConverter
{
    // 指定该转换器处理Pool类型
    public bool Accepts(Type type)
    {
        return type == typeof(Pool);
    }

    public object ReadYaml(IParser parser, Type type)
    {
        var pool = new Pool();
        
        // 处理字符串标量格式(如pool: secondPool)
        if (parser.Current is Scalar scalar)
        {
            pool.Name = scalar.Value;
            parser.MoveNext();
        }
        // 处理对象序列格式(如pool: - name: firstPool)
        else if (parser.Current is SequenceStart)
        {
            parser.MoveNext(); // 跳过序列起始标记
            // 读取序列内的第一个映射对象
            if (parser.Current is MappingStart)
            {
                parser.MoveNext(); // 跳过映射起始标记
                // 定位到name字段
                if (parser.Current is Scalar key && key.Value == "name")
                {
                    parser.MoveNext();
                    if (parser.Current is Scalar value)
                    {
                        pool.Name = value.Value;
                        parser.MoveNext();
                    }
                }
                parser.MoveNext(); // 跳过映射结束标记
            }
            parser.MoveNext(); // 跳过序列结束标记
        }
        return pool;
    }

    // 如需序列化可实现此方法,示例默认输出字符串格式
    public void WriteYaml(IEmitter emitter, object value, Type type)
    {
        var pool = (Pool)value;
        emitter.Emit(new Scalar(pool.Name));
    }
}

4. 注册转换器并执行反序列化

构建反序列化器时添加自定义转换器,即可兼容两种YAML格式:

var deserializer = new DeserializerBuilder()
    .WithTypeConverter(new PoolConverter())
    .Build();

// 读取YAML文件内容并反序列化
using var reader = new StreamReader("your-yaml-file.yaml");
var jobConfig = deserializer.Deserialize<RootJobConfig>(reader);

扩展说明

如果你的业务需要处理序列中多个pool对象的场景,可将Jobs类中的Pool属性改为List<Pool>,并调整转换器的ReadYaml逻辑,遍历序列中的所有映射对象并添加到集合中。

内容的提问来源于stack exchange,提问作者Saurabh Raoot

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 22:24:55