【C#实战】Newtonsoft.Json基类子类解析

情景再现

假设你有如下类:

public class Item {
    public int Id;
    public string Name;
}

public class Weapon: Item {
    public int CurrentAmmo;
}

public class Inventory {
    public List<Item> Items;
}

 其中你序列化的是Inventory类,Items列表里混杂着Weapon和Item,这里假定Json字符串已经正确输出。

在反序列化的过程中,你的Weapon数据并没有转换成Item,因为Items已经是显式指明了List<Item>,被Populate的实例已经明确为Item,你无法把被当成Item的Weapon强转回Weapon。

解决办法

创建一个JsonConverter,在ReadJson中读一次Json,找特定标志(比如CurrentAmmo),根据标志是否存在来创建对应类的实例。

namespace InventorySystem.Utilities
{
	public class ItemConverter : JsonConverter<Item>
	{
		public override void WriteJson(JsonWriter writer, Item value, JsonSerializer serializer){}

		public override Item ReadJson(JsonReader reader, Type objectType, Item existingValue, bool hasExistingValue,
			JsonSerializer serializer)
		{
			var jObj = JObject.Load(reader);
			if (jObj["CurrentAmmo"] != null)
			{
				return GetItem<Weapon>(jObj); 
			}

			return GetItem<Item>(jObj);
		}

		private T GetItem<T>(JObject obj)
		{
			return obj.ToObject<T>();
		}
	}
}

现在你可以在反序列化后顺利的把被当成Item的Weapon强转成Weapon了。

鸣谢

AStar

  • 6
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值