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

如何使用System.Text.Json反序列化JSON至readonly struct?

解决System.Text.Json反序列化readonly struct的方案

针对readonly struct无法直接反序列化的问题,用System.Text.Json可以通过以下几种方式实现,同时保留readonly特性:

1. 利用构造函数绑定(推荐)

System.Text.Json会自动匹配构造函数参数与JSON属性名(默认大小写敏感),通过构造函数为readonly字段赋值,这是最通用的方案。

示例代码:

public readonly struct User
{
    public readonly string Name { get; }
    public readonly int Age { get; }

    // 参数名与JSON键一一对应
    public User(string name, int age)
    {
        Name = name;
        Age = age;
    }
}

// 反序列化调用
var json = "{\"Name\":\"Alice\",\"Age\":30}";
var user = JsonSerializer.Deserialize<User>(json);

如果JSON键与参数名大小写不匹配,可使用[JsonPropertyName]标注构造函数参数:

public readonly struct User
{
    public readonly string Name { get; }
    public readonly int Age { get; }

    public User([JsonPropertyName("name")] string name, [JsonPropertyName("age")] int age)
    {
        Name = name;
        Age = age;
    }
}

2. 无参数构造函数+初始化器(仅.NET 6+)

.NET 6及以上版本允许readonly struct定义显式无参数构造函数,System.Text.Json会通过对象初始化器的方式为readonly字段赋值。

示例代码:

public readonly struct User
{
    public readonly string Name { get; }
    public readonly int Age { get; }

    // 必须显式定义无参构造函数
    public User() { }
}

// 反序列化调用
var json = "{\"Name\":\"Bob\",\"Age\":25}";
var user = JsonSerializer.Deserialize<User>(json);

注意:该方法在.NET 5及以下版本不适用,因为旧版本不支持readonly struct有显式无参构造函数。

3. 自定义JsonConverter

如果上述方案无法满足需求,可以手动实现自定义转换器,解析JSON后直接创建readonly struct实例。

示例代码:

public class UserConverter : JsonConverter<User>
{
    public override User Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        if (reader.TokenType != JsonTokenType.StartObject)
            throw new JsonException("无效的JSON对象格式");

        string? name = null;
        int age = 0;

        while (reader.Read())
        {
            if (reader.TokenType == JsonTokenType.EndObject)
                break;

            if (reader.TokenType == JsonTokenType.PropertyName)
            {
                var propName = reader.GetString()!;
                reader.Read();

                switch (propName)
                {
                    case "Name":
                        name = reader.GetString();
                        break;
                    case "Age":
                        age = reader.GetInt32();
                        break;
                    default:
                        reader.Skip(); // 跳过未知属性
                        break;
                }
            }
        }

        return new User(name!, age);
    }

    public override void Write(Utf8JsonWriter writer, User value, JsonSerializerOptions options)
    {
        writer.WriteStartObject();
        writer.WriteString("Name", value.Name);
        writer.WriteNumber("Age", value.Age);
        writer.WriteEndObject();
    }
}

// 使用转换器
var options = new JsonSerializerOptions();
options.Converters.Add(new UserConverter());
var json = "{\"Name\":\"Charlie\",\"Age\":35}";
var user = JsonSerializer.Deserialize<User>(json, options);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 18:33:10