← Назад к вопросам

Что происходит во время Сериализации в JSON?

1.0 Junior🔥 171 комментариев
#C# и ООП#Коллекции и структуры данных#Сеть и мультиплеер

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI7 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Подробный разбор процесса сериализации в JSON

Сериализация в JSON (JavaScript Object Notation) — это процесс преобразования структур данных или объектов в памяти приложения в текстовую строку, соответствующую стандарту JSON. В контексте Unity (использующей преимущественно C#) этот процесс имеет свои особенности, учитывая архитектуру движка.

Ключевые этапы сериализации

1. Анализ структуры объекта Сериализатор (например, JsonUtility в Unity или популярная библиотека Newtonsoft.Json) начинает с получения метаданных типа объекта через System.Reflection. Он определяет:

  • Публичные поля (в JsonUtility) или свойства (в других сериализаторах).
  • Их типы данных (примитивы, массивы, вложенные объекты).
  • Атрибуты, влияющие на процесс (например, [SerializeField], [NonSerialized]).

2. Рекурсивное преобразование данных в JSON-токены Процесс проходит иерархически, создавая элементы JSON:

  • Примитивные типы (int, float, string, bool) преобразуются напрямую в свои строковые или числовые представления.
  • Массивы и списки (List<T>, T[]) преобразуются в JSON-массивы [...].
  • Сложные объекты (классы и структуры) преобразуются в JSON-объекты {...}, где имена полей становятся ключами.
  • Специальные типы Unity (как Vector3, Color) обычно требуют кастомной обработки, так как по умолчанию они не сериализуются в удобочитаемый JSON.

3. Форматирование и запись строки На этом этапе строится итоговая текстовая строка с соблюдением синтаксиса JSON:

  • Расстановка фигурных и квадратных скобок.
  • Правильное экранирование специальных символов в строках (например, кавычек \").
  • Добавление разделителей (запятых между элементами, двоеточий между ключами и значениями).

Пример сериализации в Unity

Рассмотрим простой класс и его сериализацию с помощью встроенного JsonUtility:

using UnityEngine;

[System.Serializable]
public class PlayerData
{
    public string playerName;
    public int score;
    public Vector3 position; // Потребует кастомного решения
    public string[] inventory;
}

public class SerializationExample : MonoBehaviour
{
    void Start()
    {
        PlayerData data = new PlayerData()
        {
            playerName = "Hero",
            score = 1500,
            position = new Vector3(1.5f, 2.0f, 3.5f),
            inventory = new string[] { "Sword", "Potion", "Key" }
        };

        // Процесс сериализации происходит здесь
        string jsonString = JsonUtility.ToJson(data, prettyPrint: true);
        Debug.Log(jsonString);
    }
}

Вывод JsonUtility (без обработки Vector3):

{
    "playerName": "Hero",
    "score": 1500,
    "position": {
        "x": 1.5,
        "y": 2.0,
        "z": 3.5
    },
    "inventory": ["Sword", "Potion", "Key"]
}

Важные нюансы в Unity:

  • JsonUtility работает ТОЛЬКО с публичными полями или полями, помеченными атрибутом [SerializeField]. Свойства игнорируются.
  • Производительность vs Гибкость: JsonUtility (основанный на UnityEngine.JsonSerialize) быстрее, но менее функционален. Для сложных задач (сериализация словарей, полиморфных коллекций) часто используют Newtonsoft.Json (Json.NET), доступный через Package Manager.
  • Циклические ссылки могут вызвать бесконечную рекурсию и исключение. Требуют специальной обработки через атрибуты или настройки сериализатора.
  • Сериализация MonoBehaviour и ScriptableObject имеет ограничения. Чаще сериализуют отдельные классы данных, а не компоненты целиком.

Распространенные проблемы и их решения

  • Поле не сериализуется: Проверьте модификатор доступа (должно быть public или иметь [SerializeField]).
  • Исключение при сериализации интерфейса: Используйте атрибут [JsonConverter] или сохраняйте конкретный тип.
  • Сериализация Unity-специфичных типов: Создайте кастомный конвертер или сериализуйте их в промежуточный формат (например, Vector3 в массив из 3 чисел).
  • Потеря точности у float: JSON не различает float и double, что может привести к потере данных при высокой точности.

Процесс сериализации — фундаментальный для сохранения игрового состояния, конфигурации, обмена данными с сервером. Понимание его внутренних механизмов позволяет избегать частых ошибок и оптимизировать работу с данными в Unity-проектах.