Ваш пользовательский сериализатор, производный от JsonConverter
, требует доработки и содержит несколько ошибок.Во-первых, обратите внимание, что вы пытаетесь сериализовать / десериализовать Dictionary
из Vector2Int
, а не просто переменную Vector2Int
.
Это так:
public Dictionary<Vector2Int, Collection> cardLocations.
not
public Vector2Int cardLocations;
Из-за вышеприведенного утверждения ваша override bool CanConvert(Type objectType)
функция должна проверять typeof(Dictionary<Vector2Int, Collection>)
не typeof(Vector2Int)
.Кроме того, вам также необходимо добавить проверки, чтобы определить, когда запускать пользовательский десериализатор.
Сериализация :
1 . В *Функция 1027 *, которая сериализует json, вам нужно только настроить часть Dictionary<Vector2Int, Collection>
, которая вызывает исключение, поэтому убедитесь, что пользовательский код запускает only , когда тип Dictionary<Vector2Int, Collection>
.Вы можете сделать это, поместив код внутри if (value is Dictionary<Vector2Int, Collection>)
.
2 . Получите словарь для сериализации из второго аргумента.Вызовите writer.WriteStartArray()
, чтобы вы записали каждое значение в виде массива.Теперь выполните цикл по Dictionary
, запишите ключ с помощью writer.WriteValue(key)
, затем запишите значение с помощью serializer.Serialize(writer, entry.Value);
.
3 .После / вне вызова цикла writer.WriteStartArray();
затем вернитесь из этой функции.
Если if (value is Dictionary<Vector2Int, Collection>)
из # 1 равно false
, просто позвоните writer.WriteStartObject()
, а затем writer.WriteEndObject()
.
De-Сериализация :
4 . Определить, когда запускать пользовательский десериализатор
Мы использовали if (value is Dictionary<Vector2Int, Collection>)
в # 1 при сериализациичтобы определить, должен ли пользовательский код сериализатора выполняться, но для десериализации, мы используем if (reader.TokenType == JsonToken.StartArray)
, чтобы определить, достигли ли мы части массива, где мы выполнили нашу пользовательскую сериализацию в функции ReadJson
.
5 . Используйте JArray.Load(reader);
для получения данных массива, которые мы сериализовали.В возвращенном массиве первый элемент в нем является ключом в Dictionary
. Второй элемент - это значение в Dictionary
.Третий элемент - это второй ключ в Dictionary
.Четвертый элемент - это второе значение в Dictionary
и т. Д.
6 . Разделяйте ключи и значения в JArray
.
.Зацикливайте шаг JArray
на 2
вместо 1
.Увеличивая на 2
, ключ можно легко получить с помощью JArray[loop + 0]
, а значение можно получить в том же цикле с помощью JArray[loop + 1]
.
for (int i = 0; i < jArray.Count; i += 2)
{
//Key
string key = jArray[i + 0].ToString();
//Value
string value = jArray[i + 1].ToString();
}
7 .Получите ключ в формате Vector2Int
.
Просто десериализуйте ключ из # 6 в Vector2Int
с помощью JsonConvert.DeserializeObject<Vector2Int>(key)
.
8.. Получить значение в формате Collection
.
Просто десериализовать значение из # 6 в Collection
с помощью JsonConvert.DeserializeObject<Collection>(value)
.
9 . Восстановите данные
Создайте новый экземпляр Dictionary<Vector2Int, Collection>
, затем добавьте в него как ключ из # 7 , так и значение из # 8 и затем верните его из функции ReadJson
.
Если if (reader.TokenType == JsonToken.StartArray)
из # 4 равно false
, просто создайте и верните новый экземпляр Dictionary<Vector2Int, Collection>
из функции ReadJson
без добавления ключа или значения.
class Vec2DictionaryConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return typeof(Dictionary<Vector2Int, Collection>).IsAssignableFrom(objectType);
}
//Deserialize json to an Object
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
//Debug.Log("De-serializing!");
if (reader.TokenType == JsonToken.StartArray)
{
// Load JArray from stream
JArray jArray = JArray.Load(reader);
//Where to re-create the json data into
Dictionary<Vector2Int, Collection> dict = new Dictionary<Vector2Int, Collection>();
if (jArray == null || jArray.Count < 2)
{
return dict;
}
//Do the loop faster with +=2
for (int i = 0; i < jArray.Count; i += 2)
{
//first item = key
string firstData = jArray[i + 0].ToString();
//second item = value
string secondData = jArray[i + 1].ToString();
//Create Vector2Int key data
Vector2Int vect = JsonConvert.DeserializeObject<Vector2Int>(firstData);
//Create Collection value data
Collection values = JsonConvert.DeserializeObject<Collection>(secondData);
//Add both Key and Value to the Dictionary if key doesnt exit yet
if (!dict.ContainsKey(vect))
dict.Add(vect, values);
}
//Return the Dictionary result
return dict;
}
return new Dictionary<Vector2Int, Collection>();
}
//SerializeObject to Json
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
//Debug.Log("Serializing!");
if (value is Dictionary<Vector2Int, Collection>)
{
//Get the Data to serialize
Dictionary<Vector2Int, Collection> dict = (Dictionary<Vector2Int, Collection>)value;
//Loop over the Dictionary array and write each one
writer.WriteStartArray();
foreach (KeyValuePair<Vector2Int, Collection> entry in dict)
{
//Write Key (Vector)
serializer.Serialize(writer, entry.Key);
//Write Value (Collection)
serializer.Serialize(writer, entry.Value);
}
writer.WriteEndArray();
return;
}
writer.WriteStartObject();
writer.WriteEndObject();
}
}
Использование :
Сериализация
string json = JsonConvert.SerializeObject(userInfo, new Vec2DictionaryConverter());
Десериализация
UserInfo obj = JsonConvert.DeserializeObject<UserInfo>(json, new Vec2DictionaryConverter());