질문:
Json.Net의 TypeNameHandling.Auto
설정을 사용하여 다형성 하위 개체가 포함된 C# 클래스를 직렬화/역직렬화하는 것은 매우 편리합니다. 그러나 이 접근 방식은 직렬화된 JSON에 추가 $type
필드를 도입하여 오버헤드를 추가합니다.
해결책:
인코딩 하위 유형 속성이 있는 사용자 정의 기본 클래스:
하위 유형 정보를 컨테이너 클래스에 저장하는 대신 기본 클래스에 속성으로 추가하세요.
<code class="language-csharp">[JsonConverter(typeof(SubTypeClassConverter))] public class SubTypeClassBase { [JsonConverter(typeof(StringEnumConverter))] public SubType Type { get { return typeToSubType[GetType()]; } } }</code>
이 속성은 개체의 런타임 유형을 반영하여 열거형 값으로 인코딩합니다. typeToSubType
유형을 열거형 값에 매핑하려면 사전을 자체적으로 구현해야 합니다.
역직렬화를 위한 사용자 정의 JsonConverter:
기본 클래스에 대한 사용자 정의 JsonConverter
만들기:
<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
메소드는 자체적으로 구현되어야 하며 열거형 값에 따라 해당 유형을 반환합니다.
장점:
$type
필드를 제거하여 크기를 줄입니다. 참고: 및 GetTypeFromSubType
의 특정 구현과 typeToSubType
메소드 구현은 WriteJson
코드 조각에서 생략되었으며, 특정 SubType
열거형 및 하위 클래스 쓰기. SubType
열거형에는 가능한 모든 하위 유형이 포함되어야 합니다. typeToSubType
사전은 각 하위 클래스의 유형을 해당 SubType
열거형 값에 매핑해야 합니다. GetTypeFromSubType
메소드는 역방향 매핑을 수행해야 합니다.
위 내용은 '$ type'필드없이 JSON.NET에서 다형성 하위 물체의 사용자 정의 직렬화를 어떻게 달성 할 수 있습니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!