我正在尝试反序列化一个复杂的对象,它可以包含同一个类的实例(WorldInstance,它可以包含更多的WorldInstances),但它抛出了这个异常,我不知道为什么,或者如何修复它。 / p>
我知道这有点模糊,但我不知道需要什么信息,所以我会发布任何有关我的信息。
编辑1:这是我正在尝试序列化的整个课程。 http://pastebin.com/QTNH1HZH
我认为它在使用已发现的文件时失败,在第691行,即使它不应该对该数据做任何事情。
答案 0 :(得分:0)
您的问题是您正在尝试使Json.NET反序列化只获取数组属性discoveredTiles
,如以下简化版本的类所示:
public class WorldInstance
{
protected WorldTile[,] m_Tiles;
protected bool[,] m_Discovered;
public WorldInstance(WorldTile[,] tiles)
{
m_Tiles = tiles;
m_Discovered = new bool[m_Tiles.GetLength(0), m_Tiles.GetLength(1)];
}
public WorldTile[,] tiles
{
get
{
return m_Tiles;
}
}
public bool[,] discoveredTiles
{
get
{
return m_Discovered;
}
}
}
public class WorldTile
{
}
即使数组是预先分配的并且与JSON数组具有相同的长度,目前也没有实现,因为Json.NET将尝试将反序列化的项添加到预先分配的数组中,这当然是不可能的。 (请注意,tiles
属性将通过将其传递给构造函数来进行反序列化,将JSON属性名称与构造函数参数名称相匹配。)
对于1d数组属性,抛出的异常解释了这个问题:
System.NotSupportedException: Collection was of a fixed size.
at System.SZArrayHelper.Add[T](T value)
at Newtonsoft.Json.Utilities.CollectionWrapper`1.Add(T item) in C:\Development\Releases\Json\Working\Newtonsoft.Json\Working-Signed\Src\Newtonsoft.Json\Utilities\CollectionWrapper.cs:line 76
at Newtonsoft.Json.Utilities.CollectionWrapper`1.System.Collections.IList.Add(Object value) in C:\Development\Releases\Json\Working\Newtonsoft.Json\Working-Signed\Src\Newtonsoft.Json\Utilities\CollectionWrapper.cs:line 194
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObjectUsingCreatorWithParameters(JsonReader reader, JsonObjectContract contract, JsonProperty containerProperty, ObjectConstructor`1 creator, String id) in C:\Development\Releases\Json\Working\Newtonsoft.Json\Working-Signed\Src\Newtonsoft.Json\Serialization\JsonSerializerInternalReader.cs:line 2030
但是对于2d数组,引发的InvalidCastException
不那么亮。
此问题有两种解决方法:
将受保护的构造函数添加到包含WorldInstance
参数的bool[,] discoveredTiles
并将其标记为[JsonConstructor]
,例如:
[JsonConstructor]
protected WorldInstance(WorldTile[,] tiles, bool[,] discoveredTiles)
{
if (tiles == null || discoveredTiles == null)
throw new ArgumentNullException();
// Ensure the tiles and discoveredTiles arrays have the same sizes
if (tiles.GetLength(0) != discoveredTiles.GetLength(0) || tiles.GetLength(1) != discoveredTiles.GetLength(1))
throw new InvalidOperationException("tiles.GetLength(0) != discoveredTiles.GetLength(0) || tiles.GetLength(1) != discoveredTiles.GetLength(1)");
m_Tiles = tiles;
m_Discovered = discoveredTiles;
}
请注意,参数名称discoveredTiles
必须与相应的序列化属性名称相同。
为discoveredTiles
添加私有或受保护的setter,并使用[JsonProperty]
标记:
[JsonProperty]
public bool[,] discoveredTiles
{
get
{
return m_Discovered;
}
protected set
{
if (value == null)
throw new ArgumentNullException();
// Ensure the tiles and discoveredTiles arrays have the same sizes
if (tiles != null && tiles.GetLength(0) != value.GetLength(0) || tiles.GetLength(1) != value.GetLength(1))
throw new InvalidOperationException("tiles != null && tiles.GetLength(0) != value.GetLength(0) || tiles.GetLength(1) != value.GetLength(1)");
m_Discovered = value;
}
}