如何使用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
相关产品推荐
相关产品推荐

