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

文章目录

  • 二、实现步骤
    • 1.先扩展JsonConverter
    • 2.基类,子类,管理数据类示例
    • 3.实际使用
  • 总结


假如在管理数据的链表中的子类还有链表保存着带基类的数据类型,而且实际数据又是子类实例,则可以使用多个扩展的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
    {
        /// 
        /// Create an instance of objectType, based properties in the JSON object
        /// 
        /// type of object expected
        /// 
        /// contents of JSON object that will be deserialized
        /// 
        /// 
        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. 如果您觉得此文还不错的请点赞加收藏哦,您的鼓励是对我持续创作的动力。感谢您的阅读。

你可能感兴趣的:(c#,链表,json)