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

YamlDotNet不支持KeyValuePair反序列化,求特定场景替代方案

解决YamlDotNet反序列化为IEnumerable<KeyValuePair<string, string>>的方案

针对无法改用Dictionary<string, string>,且YamlDotNet默认不支持KeyValuePair<,>类型反序列化的场景,以下是几个可行方案:

方案1:自定义YAML类型转换器

实现IYamlTypeConverter接口,专门处理KeyValuePair<string, string>的反序列化逻辑,再将转换器注册到反序列化器中。

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

public class KeyValuePairConverter : IYamlTypeConverter
{
    public bool Accepts(Type type)
    {
        return type.IsGenericType && type.GetGenericTypeDefinition() == typeof(KeyValuePair<,>)
               && type.GetGenericArguments()[0] == typeof(string)
               && type.GetGenericArguments()[1] == typeof(string);
    }

    public object ReadYaml(IParser parser, Type type)
    {
        parser.Consume<MappingStart>();
        
        var key = parser.Consume<Scalar>().Value;
        var value = parser.Consume<Scalar>().Value;
        
        parser.Consume<MappingEnd>();
        
        return new KeyValuePair<string, string>(key, value);
    }

    public void WriteYaml(IEmitter emitter, object value, Type type)
    {
        var kvp = (KeyValuePair<string, string>)value;
        emitter.Emit(new MappingStart());
        emitter.Emit(new Scalar(kvp.Key));
        emitter.Emit(new Scalar(kvp.Value));
        emitter.Emit(new MappingEnd());
    }
}

使用示例:

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

var yaml = @"
- key1: value1
- key2: value2
- key3: value3
";

var result = deserializer.Deserialize<IEnumerable<KeyValuePair<string, string>>>(yaml);

方案2:通过中间类型转换

先将YAML反序列化为List<Dictionary<string, string>>,再通过LINQ转换为目标类型,无需自定义转换器,逻辑直观:

var deserializer = new DeserializerBuilder().Build();
var yaml = @"
- key1: value1
- key2: value2
- key3: value3
";

var intermediate = deserializer.Deserialize<List<Dictionary<string, string>>>(yaml);
var result = intermediate.SelectMany(dict => dict).AsEnumerable();

方案3:自定义INodeDeserializer

如果需要更底层的反序列化控制,可实现INodeDeserializer接口扩展YamlDotNet的核心反序列化逻辑:

using YamlDotNet.Core;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NodeDeserializers;

public class KeyValuePairNodeDeserializer : INodeDeserializer
{
    private readonly INodeDeserializer innerDeserializer;

    public KeyValuePairNodeDeserializer(INodeDeserializer innerDeserializer)
    {
        this.innerDeserializer = innerDeserializer;
    }

    public bool Deserialize(IParser parser, Type expectedType, Func<IParser, Type, object> nestedObjectDeserializer, out object value)
    {
        if (expectedType.IsGenericType && expectedType.GetGenericTypeDefinition() == typeof(KeyValuePair<,>)
            && expectedType.GetGenericArguments()[0] == typeof(string)
            && expectedType.GetGenericArguments()[1] == typeof(string))
        {
            parser.Consume<MappingStart>();
            var key = (string)nestedObjectDeserializer(parser, typeof(string));
            var val = (string)nestedObjectDeserializer(parser, typeof(string));
            parser.Consume<MappingEnd>();
            
            value = new KeyValuePair<string, string>(key, val);
            return true;
        }

        return innerDeserializer.Deserialize(parser, expectedType, nestedObjectDeserializer, out value);
    }
}

使用示例:

var deserializer = new DeserializerBuilder()
    .WithNodeDeserializer(inner => new KeyValuePairNodeDeserializer(inner))
    .Build();

var yaml = @"
- key1: value1
- key2: value2
- key3: value3
";

var result = deserializer.Deserialize<IEnumerable<KeyValuePair<string, string>>>(yaml);

内容的提问来源于stack exchange,提问作者Salih Kavaf

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 08:03:34