如何将自定义TaxpayerIdentificationNumber结构体序列化为字符串并支持反序列化?
自定义结构体的字符串序列化与反序列化实现
针对你的需求,不需要用ISerializable(它主要适配.NET二进制序列化场景),主流JSON序列化库都支持通过自定义转换器实现类似DateTime的特殊序列化逻辑,以下分两种常用库给出具体实现:
方案一:System.Text.Json(.NET Core/.NET 5+ 默认库)
结构体与转换器实现
using System; using System.Text.Json; using System.Text.Json.Serialization; public struct TaxpayerIdentificationNumber { private readonly long _number; public TaxpayerIdentificationNumber(long number) { // 可添加13位数字校验逻辑 if (number.ToString().Length != 13) throw new ArgumentException("税号必须为13位数字", nameof(number)); _number = number; } // 提供内部字段的访问入口,供转换器使用 public long GetNumber() => _number; } public class TinJsonConverter : JsonConverter<TaxpayerIdentificationNumber> { // 序列化:将结构体转为纯数字字符串 public override void Write(Utf8JsonWriter writer, TaxpayerIdentificationNumber value, JsonSerializerOptions options) { writer.WriteStringValue(value.GetNumber().ToString()); } // 反序列化:从字符串还原为结构体 public override TaxpayerIdentificationNumber Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { if (reader.TokenType != JsonTokenType.String) throw new JsonException("税号必须是字符串格式"); if (!long.TryParse(reader.GetString(), out long number)) throw new JsonException("无效的税号数字格式"); return new TaxpayerIdentificationNumber(number); } }
使用示例
// 初始化结构体 var tin = new TaxpayerIdentificationNumber(1234567890123); // 配置序列化选项 var options = new JsonSerializerOptions(); options.Converters.Add(new TinJsonConverter()); // 序列化结果为 "1234567890123" string serialized = JsonSerializer.Serialize(tin, options); // 反序列化 var deserializedTin = JsonSerializer.Deserialize<TaxpayerIdentificationNumber>(serialized, options);
方案二:Newtonsoft.Json(Json.NET)
结构体与转换器实现
using System; using Newtonsoft.Json; public struct TaxpayerIdentificationNumber { private readonly long _number; public TaxpayerIdentificationNumber(long number) { if (number.ToString().Length != 13) throw new ArgumentException("税号必须为13位数字", nameof(number)); _number = number; } public long GetNumber() => _number; } public class TinJsonConverter : JsonConverter<TaxpayerIdentificationNumber> { public override void WriteJson(JsonWriter writer, TaxpayerIdentificationNumber value, JsonSerializer serializer) { writer.WriteValue(value.GetNumber().ToString()); } public override TaxpayerIdentificationNumber ReadJson(JsonReader reader, Type objectType, TaxpayerIdentificationNumber existingValue, bool hasExistingValue, JsonSerializer serializer) { if (reader.Value is not string tinStr) throw new JsonException("税号必须是字符串格式"); if (!long.TryParse(tinStr, out long number)) throw new JsonException("无效的税号数字格式"); return new TaxpayerIdentificationNumber(number); } public override bool CanConvert(Type objectType) { return objectType == typeof(TaxpayerIdentificationNumber); } }
使用示例
可以通过特性直接标记结构体,无需手动配置选项:
[JsonConverter(typeof(TinJsonConverter))] public struct TaxpayerIdentificationNumber { /* 结构体代码 */ } // 序列化 var tin = new TaxpayerIdentificationNumber(1234567890123); string serialized = JsonConvert.SerializeObject(tin); // 结果为 "1234567890123" // 反序列化 var deserializedTin = JsonConvert.DeserializeObject<TaxpayerIdentificationNumber>(serialized);
补充说明
DateTime的特殊序列化逻辑,本质也是序列化库内置了对应的转换器,上述自定义转换器的思路和它完全一致,能让你的结构体实现相同的"纯字符串"序列化效果。
内容的提问来源于stack exchange,提问作者Destall
相关产品推荐
相关产品推荐

