【问题标题】:JSON deserializer inherited generic typeJSON 反序列化器继承的泛型类型
【发布时间】:2015-09-21 11:49:08
【问题描述】:

我在将一些 JSON 字符串反序列化为 c# 对象时遇到问题。

假设我有以下代码:

public class A
{
    public string Name { get; set; }
}

public class B : A
{
    public int Age { get; set; }
}

public class C
{
    public ObservableCollection<A> As
    {
        get;
        set;
    }
}

我序列化以下对象_c

C _c = new C();
_c.As.Add(new B() { Name = "Max", Age = 4 });

这很好用。

但是我无法反序列化创建的 JSON 字符串并创建 B 的实例,因为 ObservableCollection 被声明为 A 作为泛型类型。有没有办法告诉 Newtonsoft.Json 使用 B 而不是 A

非常感谢。

【问题讨论】:

  • 我还以为Json net使用了实例...

标签: c# json generics serialization json.net


【解决方案1】:

似乎您解决了它,但您可以通过更改您的类 C 约束来实现相同的目标,而无需使用任何自定义 JSON 转换器。见下文:

public class C<T> where T : A
{
    private ObservableCollection<T> _as = new ObservableCollection<T>();

    public ObservableCollection<T> As
    {
        get { return _as; }
        set { _as = value; }
    }
}

然后像反序列化一样

var _c = new C<B>();
_c.As.Add(new B() { Name = "Max", Age = 4 });

var serialized = JsonConvert.SerializeObject(_c);
var deserialized = JsonConvert.DeserializeObject<C<B>>(serialized); // B

【讨论】:

  • 谢谢,好像也不错。但这只有在我可以访问 C 并且它不在第三方库中时才有效。
  • 好的,你在问题中忽略了这个细节:)
  • @BendEg “但这只有在我可以访问 C 并且它不在第三方库中时才有效” - 你如何建议添加 [Newtonsoft.Json.JsonConverter(typeof(BCJsonConverter))] 属性您对第三方库的解决方案?
  • 好的,我必须完成我的回答。 As 是一个虚拟方法,它在类 D 中被覆盖,它继承自 C。我更新了我的答案。抱歉,缺少信息...
【解决方案2】:

解决了编写自定义 JsonConverter 的问题:

public class BCJsonConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return true;
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var currentType = (existingValue as System.Collections.ObjectModel.ObservableCollection<A>);

        currentType.Clear();

        var des = serializer.Deserialize<IList<B>>(reader);

        foreach (var toAdd in des)
        {
            currentType.Add(toAdd);
        }

        return currentType;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        serializer.Serialize(writer, value);
    }
}

public class C
{
    public virtual ObservableCollection<A> As
    {
        get;
        set;
    }
}

public class D : C
{
    [Newtonsoft.Json.JsonConverter(typeof(BCJsonConverter))]
    public override ObservableCollection<A> As
    {
        get;
        set;
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多