Soalan:
Sangat mudah untuk menggunakan persediaan TypeNameHandling.Auto
Json.Net untuk mensiri/menyahserialisasikan kelas C# yang mengandungi sub-objek polimorfik. Walau bagaimanapun, pendekatan ini memperkenalkan medan $type
tambahan ke dalam JSON bersiri, menambah overhed.
Penyelesaian:
Kelas asas tersuai dengan sifat subjenis pengekodan:
Daripada menyimpan maklumat subjenis dalam kelas kontena, tambahkannya sebagai atribut kepada kelas asas:
<code class="language-csharp">[JsonConverter(typeof(SubTypeClassConverter))] public class SubTypeClassBase { [JsonConverter(typeof(StringEnumConverter))] public SubType Type { get { return typeToSubType[GetType()]; } } }</code>
Harta ini mencerminkan jenis masa jalan objek, mengekodnya sebagai nilai penghitungan. typeToSubType
Kamus perlu dilaksanakan sendiri untuk memetakan jenis kepada nilai penghitungan.
Penukar Json Tersuai untuk penyahserikatan:
Buat tersuai JsonConverter
untuk kelas asas:
<code class="language-csharp">public class SubTypeClassConverter : JsonConverter { // 读取 JSON 并确定实际类型 public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { var token = JToken.Load(reader); var typeToken = token["Type"]; var actualType = SubTypeClassBase.GetTypeFromSubType(typeToken.ToObject<SubType>(serializer)); // 使用 GetTypeFromSubType 方法 if (existingValue == null || existingValue.GetType() != actualType) { // 创建实际的对象实例 var contract = serializer.ContractResolver.ResolveContract(actualType); existingValue = contract.DefaultCreator(); } // 使用 "Populate" 方法避免无限递归 using (var subReader = token.CreateReader()) { serializer.Populate(subReader, existingValue); } return existingValue; } // ...其他方法 (WriteJson 等) ... }</code>
GetTypeFromSubType
perlu dilaksanakan dengan sendirinya dan mengembalikan jenis yang sepadan mengikut nilai penghitungan.
Kelebihan:
$type
berlebihan dalam output JSON, mengurangkan saiznya. Nota: Pelaksanaan khusus dan GetTypeFromSubType
, serta pelaksanaan kaedah typeToSubType
, ditinggalkan dalam coretan kod WriteJson
, yang perlu ditakrifkan mengikut penghitungan SubType
khusus dan penulisan subkelas. SubType
Enum harus mengandungi semua subjenis yang mungkin. Kamus typeToSubType
hendaklah memetakan setiap jenis subkelas kepada nilai penghitungan SubType
yang sepadan. Kaedah GetTypeFromSubType
harus melakukan pemetaan terbalik.
Atas ialah kandungan terperinci Bagaimanakah Saya Boleh Mencapai Pensiri Tersuai Objek Anak Polimorfik dalam Json.Net Tanpa Medan '$type'?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!