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

为何无法将YAML反序列化为C# record类型?

YamlDotNet无法反序列化C#引用类型record的原因及解决办法

问题重现

你遇到的问题是:使用YamlDotNet将YAML反序列化为C#引用类型record时抛出序列化异常,但record struct、普通struct、带get/init属性的类都能正常反序列化。错误信息如下:

Unhandled exception. (Line: 2, Col: 3, Idx: 9) - (Line: 2, Col: 3, Idx: 9): Exception during deserialization

核心原因

C#引用类型record与record struct、普通类的核心差异在于构造逻辑:

  • 引用类型record默认会生成主构造函数,编译器会自动生成基于主构造函数参数的属性初始化逻辑,但不会自动生成无参构造函数(除非显式定义)。
  • YamlDotNet的默认反序列化器优先尝试用无参构造函数实例化对象,再赋值属性;如果找不到无参构造函数,也没有明确指定要使用的构造函数,就会触发序列化异常。
  • 而record struct、普通struct会默认生成无参构造函数;带get/init的类如果没有自定义构造函数,编译器也会自动生成无参构造函数,因此能被正常处理。

解决办法

1. 显式为record添加无参构造函数

在引用类型record中手动定义无参构造函数,让YamlDotNet可以正常实例化对象:

public record User(string Name, int Age)
{
    // 显式添加无参构造函数,委托给主构造函数初始化默认值
    public User() : this(string.Empty, 0) { }
}

2. 标记YamlDotNet使用主构造函数反序列化

通过[YamlConstructor]属性指定反序列化时使用record的主构造函数,让YamlDotNet直接通过构造函数参数完成初始化:

public record User
{
    public string Name { get; init; }
    public int Age { get; init; }

    // 标记该构造函数为反序列化使用的构造函数
    [YamlConstructor]
    public User(string name, int age)
    {
        Name = name;
        Age = age;
    }
}

如果是简洁写法的record,可配合YamlMember属性精准映射YAML字段与构造参数:

public record User(
    [property: YamlMember(Alias = "name")] string Name,
    [property: YamlMember(Alias = "age")] int Age
);

3. 升级YamlDotNet到最新版本

较旧版本的YamlDotNet对C# record的支持不完善,升级到13.x及以上的最新稳定版后,对引用类型record的处理逻辑已优化,可能无需额外修改即可正常反序列化。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 06:05:29