我正在尝试反序列化描述以下内容的 json:
Item 类型的对象列表,每个 Item 包含一些属性以及 Effect 类型对象的列表“配方”,其中包含自己的三个属性( Action 、值和目标)。
当我使用“JsonConvert.SerializeObject”序列化我的列表时,我得到以下 json:
[
{
"name": "WOOD",
"yield": 1.0,
"recipe": [
{
"action": "ADD",
"value": 1.0,
"target": "WOOD"
}
],
"count": 0.0,
"numWorkers": 0,
"id": 1
},
{
"name": "CLAY",
"yield": 2.0,
"recipe": [
{
"action": "ADD",
"value": 2.0,
"target": "CLAY"
}
],
"count": 0.0,
"numWorkers": 0,
"id": 2
},
{
"name": "SPEAR",
"yield": 0.5,
"recipe": [
{
"action": "ADD",
"value": 0.5,
"target": "SPEAR"
},
{
"action": "SUB",
"value": 1.0,
"target": "WOOD"
},
{
"action": "SUB",
"value": 5.0,
"target": "CLAY"
}
],
"count": 0.0,
"numWorkers": 0,
"id": 3
},
{
"name": "STICK",
"yield": 4.0,
"recipe": [
{
"action": "ADD",
"value": 4.0,
"target": "STICK"
},
{
"action": "SUB",
"value": 1.0,
"target": "WOOD"
}
],
"count": 0.0,
"numWorkers": 0,
"id": 4
}
]
但是当我尝试使用“Items = JsonConvert.DeserializeObject<List<Item>>(jsonstring);
”反序列化时' 我收到此错误:A first chance exception of type 'System.NullReferenceException' occurred in Newtonsoft.Json.dll
我的“项目”列表为空。
当我使用 json2csharp 生成 c# 时,我得到以下信息:
public class Recipe
{
public string action { get; set; }
public double value { get; set; }
public string target { get; set; }
}
public class RootObject
{
public string name { get; set; }
public double yield { get; set; }
public List<Recipe> recipe { get; set; }
public double count { get; set; }
public int numWorkers { get; set; }
public int id { get; set; }
}
它认为我的 Item 对象是“RootObject”,它给我一个“Recipe”对象,而不是“recipe”列表中的“Effect”对象列表
这是我的游戏和类的一些代码,因此您可以看到我正在使用的内容:
public List<Item> Items;
private void Game_Load(object sender, EventArgs e)
{
Items = JsonConvert.DeserializeObject<List<Item>>(jsonstring);
}
public class Item
{
public string name;
public double yield;
public List<Effect> recipe = new List<Effect>();
public double count;
public int numWorkers;
public int id;
public Item()
{
name = "";
//configureItem();
}
public Item(string nm)
{
name = nm.ToUpper();
//configureItem();
}
public List<Effect> getRecipe() {
return recipe;
}
}
public class Effect
{
public string action;
public double value;
public string target;
public Effect(string act, double val, string tar)
{
action = act.ToUpper();
value = val;
target = tar.ToUpper();
}
}
我需要 { get; set; }
吗?对于我类(class)中的所有变量?我之前尝试添加它,但它似乎导致我的 VS 在调试期间跳过行以及各种其他怪异现象。或者它只是一个 Json 格式问题?任何帮助将不胜感激,我已经查看了整个网站和整个 Google,我正在这里扯掉我的头发。
最佳答案
您的 Event
类没有默认(无参数)构造函数,因此 Json.Net 正在尝试使用它拥有的构造函数。但是,参数名称与 JSON 中的任何内容都不匹配(不存在 act
、val
或 tar
属性)。在这种情况下,Json.Net 将为参数传递默认值(即 null
)以获取构造的对象,然后返回并尝试设置字段。问题是您的构造函数不具备处理空值的能力。它假定 act
和 tar
在调用 ToUpper()
时不会为空。这就是 NullReferenceException
的来源。
一种解决方案是重命名您的构造函数参数以匹配 JSON(为了安全,我还会添加适当的 null 检查):
public Effect(string action, double value, string target)
{
this.action = (action != null ? action.ToUpper() : null);
this.value = value;
this.target = (target != null ? target.ToUpper() : null);
}
另一种可能的解决方案是将 ToUpper
逻辑移动到属性中并提供默认构造函数。
public class Effect
{
private string _action;
public string Action
{
get { return _action; }
set { _action = (value != null ? value.ToUpper() : null); }
}
public double Value { get; set; }
private string _target;
public string Target
{
get { return _target; }
set { _target = (value != null ? value.ToUpper() : null); }
}
public Effect()
{
}
}
关于c# - Json.Net - 反序列化包含对象列表的对象列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37571690/