JSON.NET の多態性オブジェクトの逆シリアル化は、TypeNameHandling.Auto を使用すると簡単ですが、「$type」フィールドを削除する必要がある場合はどうすればよいでしょうか?
方法 1: "$type" の名前をカスタム名に変更します
残念ながら、JSON.NET の組み込みオプションでは「$type」の名前を変更できません。
方法 2: サブタイプ情報を基本クラスに追加します
コンテナ クラスを使用してサブタイプ情報を保持する代わりに、「Type」というプロパティを基本クラス (SubTypeClassBase) に追加します。
<code class="language-csharp">[JsonConverter(typeof(SubTypeClassConverter))] public class SubTypeClassBase { [JsonConverter(typeof(StringEnumConverter))] public SubType Type { get { return typeToSubType[GetType()]; } } }</code>
これにより、SubTypeClassBase 型のオブジェクトをシリアル化するときに、サブタイプ情報が常に含まれるようになります。
カスタム逆シリアル化
JSON を適切に逆シリアル化するには、「Type」プロパティを読み取り、実際の型を識別し、それに応じて逆シリアル化するカスタム JsonConverter (SubTypeClassConverter) を作成します。
<code class="language-csharp">public class SubTypeClassConverter : JsonConverter { // 重写CanConvert以支持SubTypeClassBase对象 public override bool CanConvert(Type objectType) { return objectType == typeof(SubTypeClassBase); } // 重写ReadJson以处理反序列化 public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { // 将JSON加载为JToken并获取“Type”标记 var token = JToken.Load(reader); var typeToken = token["Type"]; if (typeToken == null) throw new InvalidOperationException("无效对象"); // 根据“Type”值确定实际类型 var actualType = SubTypeClassBase.GetType(typeToken.ToObject<SubType>(serializer)); // 根据需要创建实际类型的实例 if (existingValue == null || existingValue.GetType() != actualType) { var contract = serializer.ContractResolver.ResolveContract(actualType); existingValue = contract.DefaultCreator(); } // 使用JSON数据填充实际类型 using (var subReader = token.CreateReader()) { serializer.Populate(subReader, existingValue); } return existingValue; } // 重写WriteJson以防止写入“Type”属性 public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { throw new NotImplementedException(); } }</code>
このアプローチでは、JSON.NET は SubTypeClassBase オブジェクトをシリアル化するときに自動的に「Type」属性を組み込み、SubTypeClassConverter を使用して指定された型に基づいて JSON を正しく逆シリアル化します。
この改訂された回答では、イメージを維持し、読みやすさと流れを改善するためにテキストを再構成し、元の意味を維持しながらより簡潔な言語を使用し、単語ごとの直接の置き換えを避け、より自然でわかりやすい表現を実現するために同義の代替案を選択しています。繰り返しの音調が少なくなります。
以上が「$type」フィールドを使用せずにJSON.NETで多態性オブジェクトをシリアル化する方法は?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。