我正在使用 JSON.Net 序列化我的游戏状态,但奇怪的是,一些引用变得为空。它们似乎序列化得很好(在检查输出 json 时,$id和$ref似乎设置正确(,但反序列化的对象在不应该的地方包含空引用。
我的状态如下:我有一个星球,其中包含一个瓷砖列表。每个图块都知道它的邻居(再次是图块列表(。
这是json的一小段,初始序列化:(最重要的部分是最后一行,邻居使用引用编号(
"Tiles": {
"$id": "3",
"$values": [
{
"$id": "4",
"$type": "WarSystems.Tile, Assembly-CSharp",
"_type": 0,
"ID": "161d8ca1-f086-49eb-94ba-0b5b3bbb0921",
"Position": {
"x": 0.0,
"y": 0.0,
"z": -1.71737635
},
"Normal": {
"x": 0.0,
"y": 0.0,
"z": -1.0
},
"Neighbours": [
{
"$id": "5",
"$type": "WarSystems.Tile, Assembly-CSharp",
"_type": 2,
"ID": "f34a2bb1-4a10-49db-b2d5-7980ccc55760",
"Position": {
"x": 0.2789981,
"y": -0.8586796,
"z": -1.460893
},
"Normal": {
"x": 0.1624527,
"y": -0.4999933,
"z": -0.850656152
},
"Neighbours": [
{
"$ref": "4"
},
"瓷砖"是地球上的瓷砖列表。如您所见,第一个图块有一个邻居,他们的邻居将第一个图块作为他的邻居。序列化正常,所有邻居都设置正确。
但是,当我反序列化它,然后重新序列化它时,我得到以下内容:(现在注意到邻居有一个 null(
"Tiles": {
"$id": "3",
"$values": [
{
"$id": "4",
"$type": "WarSystems.Tile, Assembly-CSharp",
"_type": 0,
"ID": "161d8ca1-f086-49eb-94ba-0b5b3bbb0921",
"Position": {
"x": 0.0,
"y": 0.0,
"z": -1.71737635
},
"Normal": {
"x": 0.0,
"y": 0.0,
"z": -1.0
},
"Neighbours": [
{
"$id": "5",
"$type": "WarSystems.Tile, Assembly-CSharp",
"_type": 2,
"ID": "f34a2bb1-4a10-49db-b2d5-7980ccc55760",
"Position": {
"x": 0.2789981,
"y": -0.8586796,
"z": -1.460893
},
"Normal": {
"x": 0.1624527,
"y": -0.4999933,
"z": -0.850656152
},
"Neighbours": [
null,
如您所见,第一个邻居现在为空。(我还检查了实际的反序列化对象,它也具有 null 引用,因此反序列化似乎出错了。当然还有更多,但这部分显示了出了什么问题,整个 json 会有点多要发布。
最后,这就是我(反(序列化的方式:
private static string SerializeState(State state)
{
return JsonConvert.SerializeObject(state, SerializerSettings);
}
private static State DeserializeState(string serialized)
{
return JsonConvert.DeserializeObject<State>(serialized, SerializerSettings);
}
使用序列化程序在它们之间共享的设置:
private static JsonSerializerSettings SerializerSettings = new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.Objects,
PreserveReferencesHandling = PreserveReferencesHandling.All,
ReferenceLoopHandling = ReferenceLoopHandling.Serialize,
Converters = new List<JsonConverter>() { new Vector3Converter() },
Formatting = Formatting.Indented
};
(Vector3Converter 用于序列化 Unity 的 Vector3。它只是将其序列化为具有 3 个字段的对象:x、y 和 z。作为磁贴中的Position
属性。
有谁知道出了什么问题,以及如何解决它?
谢谢!
编辑,星球和瓷砖类:
public class Planet
{
public Vector3 Position { get; set; }
public List<Tile> Tiles { get; set; }
public Planet(Vector3 pos, List<Tile> tiles)
{
Position = pos;
Tiles = tiles;
}
}
public class Tile
{
public Guid ID { get; set; }
[JsonRequired]
private TileType _type;
[JsonIgnore]
public TileType Type
{
get { return _type; }
set
{
if (_type != value)
{
_type = value;
if (TypeChanged != null) TypeChanged(_type);
}
}
}
public Vector3 Position { get; set; }
public Vector3 Normal { get; set; }
private List<Tile> _neighbours = new List<Tile>(6); //6 since we use a hex grid
public List<Tile> Neighbours { get { return _neighbours; } set { _neighbours = value; } }
// Events
public event System.Action<TileType> TypeChanged;
public Tile(TileType type, Vector3 pos, Vector3 normal)
{
ID = Guid.NewGuid();
Position = pos;
Normal = normal;
}
public void AddNeighbour(Tile neighbour)
{
_neighbours.Add(neighbour);
}
}
我已经解决了。一旦我在Tile
类中添加了一个空的构造函数,一切就会按预期工作。
public Tile() { } //for deserialization