c# - 某些类的自定义反序列化?
问题描述
我正在开发一个在 JSON 中有一些非常复杂的配置文件的项目。一个例子就是这样(只是一个更大的齿轮中的一个属性)
"Visuals": {
"UseAnimation": [
{
"Name": "idle",
"RunConditions": {
"cur_processed_inv": "IsZero"
}
},
{
"Name": "running",
"RunConditions": {
"cur_processed_inv": "IsGreaterThanZero"
}
}
]
}
该项目已决定使用 Newtonsoft.Json 进行转换。当前的结构方式是一系列类。在这种情况下,Visuals
和UseAnimation
是类。RunConditions
由一个名为条件的类管理,目前看起来像这样:
[Serializable]
[JsonObject(MemberSerialization.OptIn)]
public class Conditions
{
public List<ParameterCondition> ParamConditions { get; set; }
}
问题是json数据与类结构不匹配。原因很复杂,但简短的版本是基于 XML 的代码,而且在转换为 JSON 时似乎从未正确测试过这一位。如果可能的话,我不想改变数据文件,也不想改变最终保存数据的结构。理想的解决方案是制作一些可以自定义解析这个类的代码,该类由正在运行的 JSON 反序列化代码调用,如下所示:
public static Conditions Deserialize(JToken jtoken)
{
Conditions condition = new Conditions();
condition.ParamConditions = new List<ParameterCondition>();
foreach (JProperty prop in jtoken)
{
ConditionType type = (ConditionType)Enum.Parse(typeof(ConditionType), prop.Value.ToString(), true);
condition.ParamConditions.Add(new ParameterCondition()
{
Condition = type,
ParameterName = prop.Name
});
}
return condition;
}
在环顾四周时,我看到了您可以完全自定义反序列化所有内容的解决方案,但我只希望对这一部分进行反序列化。
这是针对名为Project Porcuipine的开源游戏。一些可能有帮助的位:
解决方案
步骤 1. 编写一个类来解析它,扩展 JsonConverter。
public class ConditionsJsonConvertor : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(Conditions);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
Conditions condition = new Conditions();
condition.ParamConditions = new List<ParameterCondition>();
JToken jtoken = JToken.ReadFrom(reader);
foreach (JProperty prop in jtoken)
{
ConditionType type = (ConditionType)Enum.Parse(typeof(ConditionType), prop.Value.ToString(), true);
condition.ParamConditions.Add(new ParameterCondition()
{
Condition = type,
ParameterName = prop.Name
});
}
return condition;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
Conditions conditions = (Conditions)value;
JObject jObjs = new JObject();
foreach (ParameterCondition pCondition in conditions.ParamConditions)
{
JProperty prop = new JProperty(pCondition.ParameterName, pCondition.Condition.ToString());
jObjs.Add(prop);
}
jObjs.WriteTo(writer);
}
}
第2步:在代码中,在引用解析条件时,让它知道使用哪个JsonConverter。
[JsonConverter(typeof(ConditionsJsonConvertor))]
public Conditions RunConditions { get; set; }
推荐阅读
- javascript - 使用 JS 进行分页
- heroku - 配置 GitLab CI 以部署到 heroku
- powershell - 如何在 Powershell 中提取子字符串
- r - 不按预期将消息发送到文件
- excel - 未设置对象变量或带有块变量 - 查找和替换宏 - 多次查找迭代
- ios - 有没有办法仅在通过滑动导航时忽略可访问性元素?
- javascript - 如何在 Meteor 中创建和下载文本文件?
- sql - 如何在 Where 子句中使用分组功能
- openlayers - 检查openlayers中多边形内的坐标/位置
- windows - 使用安全密码创建本地管理员帐户的隐形 powershell 脚本