首页 > 解决方案 > 使用对象支持字段反序列化通用子类

问题描述

不知道如何正确命名这个问题,但这是问题所在。

public sealed class ObjectPropertySubclassTest
{
    private sealed class CleverBaseClassConverter : JsonConverter<BaseClass>
    {
        public override bool CanWrite => false;

        public override void WriteJson(JsonWriter writer, BaseClass value, JsonSerializer serializer)
        {
            throw new NotImplementedException();
        }

        public override BaseClass ReadJson(JsonReader reader, Type objectType, BaseClass existingValue, bool hasExistingValue, JsonSerializer serializer)
        {
            var token = JToken.ReadFrom(reader);
            if (token["Components"] is JArray)
            {
                var collection=new CollectionClass();
                serializer.Populate(token.CreateReader(), collection);
                return collection;
            }
            else
            {
                if (token["Value"] is JArray)
                {
                    var obj = new SubClass<IEnumerable<BaseClass>>();
                    serializer.Populate(token.CreateReader(), obj);
                    return obj;
                }
                else
                {
                    var obj = new SubClass<object>();
                    serializer.Populate(token.CreateReader(), obj);
                    return obj;
                }
            }
        }
    }

    [JsonConverter(typeof(CleverBaseClassConverter))]
    private abstract class BaseClass
    {
        public object Value { get; set; }
    }

    private class SubClass<T>: BaseClass
    {
        public new T Value
        {
            get => (T) base.Value;
            set => base.Value = value;
        }
    }

    private sealed class CollectionClass : SubClass<IEnumerable<BaseClass>>
    {
        public IEnumerable<BaseClass> Components { get=>Value; set=>Value=value; }
        public bool ShouldSerializeValue() => false;
    }

    [Test]
    public void Test()
    {
        var item=new CollectionClass
        {
            Components=new BaseClass[] {new SubClass<string>{Value="hi"},new SubClass<int>{Value=5},   }
        };
        var json = JsonConvert.SerializeObject(item);

        var copy = JsonConvert.DeserializeObject<CollectionClass>(json);

        //why does copy.components have 4 items (2 doubling up)?
        //why does copy.value have 4 items (2 doubling up) as well?
    }
}

Serializaiton 按预期工作,但是当我将 json 反序列化为集合类时,它最终得到 4 个项目而不是 2 个(在组件中)。我在反序列化方面做错了什么吗?还有为什么它仍然为集合类序列化“值”

JSON:(我有 json 转换器来反序列化正确的子类)

{"Components":[{"Value":"hi"},{"Value":5}],"Value":[{"Value":"hi"},{"Value":5}]}

标签: c#json.netjson-deserializationsubclassing

解决方案


利用

TypeNameHandling.Auto

代替

TypeNameHandling.Object

推荐阅读