C#中,管理数据的链表以基类为类型保存子类的对象,json反序列化为某个子类,子类属性不丢失。


假如在管理数据的链表中的子类还有链表保存着带基类的数据类型,而且实际数据又是子类实例,则可以使用多个扩展的JsonConverter。

JsonConverter[] cc = new JsonConverter[2];
            cc[0] = new MDataConverter();
            cc[1] = new MDataConverter2();
            var result = JsonConvert.DeserializeObject<PathDataManage>(tJsonStr, cc);

二、实现步骤

1.先扩展JsonConverter

代码如下(示例):

    public abstract class DataCreationConverter<T> : JsonConverter
    {
        /// <summary>
        /// Create an instance of objectType, based properties in the JSON object
        /// </summary>
        /// <param name="objectType">type of object expected</param>
        /// <param name="jObject">
        /// contents of JSON object that will be deserialized
        /// </param>
        /// <returns></returns>
        protected abstract T Create(Type objectType, JObject jObject);

        public override bool CanConvert(Type objectType)
        {
            return typeof(T).IsAssignableFrom(objectType);
        }

        public override object ReadJson(JsonReader reader,
                                        Type objectType,
                                         object existingValue,
                                         JsonSerializer serializer)
        {
            // Load JObject from stream
            JObject jObject = JObject.Load(reader);

            // Create target object based on JObject
            T target = Create(objectType, jObject);

            // Populate the object properties
            serializer.Populate(jObject.CreateReader(), target);

            return target;
        }

        public override void WriteJson(JsonWriter writer,
                                       object value,
                                       JsonSerializer serializer)
        {
            throw new NotImplementedException();
        }
    }
    public class MDataConverter : DataCreationConverter<Path>
    {
        protected override Path Create(Type nObjectType, JObject nJObject)
        {
            //第一种方法:判断属性值来确认是哪个子类 
            if (FieldExists(nJObject, "OutGlueTime"))
            {
                return new SigPoint();
            }
            else if (FieldExists(nJObject, "OpenDelay"))
            {
                return new MultiPointPath();
            }
            else
            {
                return new Path();
            }
        }
        private bool FieldExists(JObject nJObject, string nPropertyName)
        {
            return nJObject[nPropertyName] != null;
        }
        private bool FieldExists(string nFieldName, JObject nJObject, out string nEntityVel)
        {
            nEntityVel = nJObject[nFieldName] == null ? "" : nJObject[nFieldName].ToString();
            return nJObject[nFieldName] != null;
        }
    }

    public class MDataConverter2 : DataCreationConverter<MPathPoint>
    {
        protected override MPathPoint Create(Type nObjectType, JObject nJObject)
        {
            //第一种方法:判断属性值来确认是哪个子类 
            if (FieldExists(nJObject, "IsArcMiddlePoint"))
            {
                return new ArcMiddlePoint();
            }
            else
            {
                return new EndPoint();
            }
        }
        private bool FieldExists(JObject nJObject, string nPropertyName)
        {
            return nJObject[nPropertyName] != null;
        }
    }

2.基类,子类,管理数据类示例

基类1代码如下(示例):

  public class Path
    {
        // 可以没有属性
    }

基类2代码如下(示例):

  public class MPathPoint //: MBaseClass
    {
        public float X { get; set; } = 0;
        public float Y { get; set; } = 0;
        public float Z { get; set; } = 0;
    }

以下两个子类继承基类1 代码如下(示例):

请注意以下的MultiPointPath 类中还有一个链表管理MPathPoint,而MPathPoint为基类,实际存储的也是子类数据。

class SigPoint : Path
    {
        public float X { get; set; } = 0;
    }

class MultiPointPath : Path
    {
     	public float OpenDelay { get; set; } = 0;
		//注意此处
     	public List<MPathPoint> PathPointsList { get; set; } = new List<MPathPoint>();
    }

以下两个子类继承基类2 代码如下(示例):

 class EndPoint : MPathPoint
    {
  	   public float Speed { get; set; } = 0;
    }
    class ArcMiddlePoint : MPathPoint
    {
       public bool IsArcMiddlePoint { get; set; } = true;
    }

管理数据类代码如下(示例):

请注意以下的PathDataManage类中,有一个链表管理Path,而Path为基类,实际存储的也是子类数据。

  class PathDataManage
    {
        public List<Path> mPathScaleList { get; set; } = new List<Path>();
    }

3.实际使用

JsonConverter[] cc = new JsonConverter[2];
            cc[0] = new MDataConverter();
            cc[1] = new MDataConverter2();
var result = JsonConvert.DeserializeObject<PathDataManage>(tJsonStr, cc);

总结

此文主要介绍了一种解决反序列化时,基类数据类型的链表存储着子类数据时的反序列化方法,并且对子类中又还有链表的情况同样适用。
给读者:
  1. 各位读者,如果您看到有疑问的,可以私信给博主,本文为原创,手写不易,有错的地方欢迎批评指正。
  2. 如果您觉得此文还不错的请点赞加收藏哦,您的鼓励是对我持续创作的动力。感谢您的阅读。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

尔雅慕客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值