假如在管理数据的链表中的子类还有链表保存着带基类的数据类型,而且实际数据又是子类实例,则可以使用多个扩展的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);
总结
此文主要介绍了一种解决反序列化时,基类数据类型的链表存储着子类数据时的反序列化方法,并且对子类中又还有链表的情况同样适用。给读者:
- 各位读者,如果您看到有疑问的,可以私信给博主,本文为原创,手写不易,有错的地方欢迎批评指正。
- 如果您觉得此文还不错的请点赞加收藏哦,您的鼓励是对我持续创作的动力。感谢您的阅读。