JavaRush /Курсы /C# SELF /Базовые примеры сериализации

Базовые примеры сериализации

C# SELF
45 уровень , 0 лекция
Открыта

1. Введение

Напоминание: Сериализация — это способ сохранить состояние объекта в виде строки, файла или потока, чтобы позже можно было восстановить этот объект (десериализовать) — и у вас снова есть объект с теми же данными.

Типичная жизненная ситуация:
1) У вас есть объект, например, пользователь с именем и возрастом.
2) Нужно это сохранить — передать по сети, записать в файл или, скажем, в формат JSON.
3) Потом данные из строки/файла достаём обратно — и снова получаем объект!

В C# это делается буквально в пару строк. Давайте посмотрим, как именно.

Наше приложение

Мы разрабатываем небольшое приложение «Менеджер контактов». Пусть у нас есть класс Person, который мы хотим сериализовать.

public class Person
{
    // Публичные свойства обязательны для сериализации!
    public string Name { get; set; }
    public int Age { get; set; }

    // Конструктор без параметров обязателен для XmlSerializer
    public Person() { }

    public Person(string name, int age)
    {
        Name = name;
        Age = age;
    }
}

Если вы не знакомы с таким синтаксисом, не переживайте — далее в курсе разберём классы и свойства подробно. Сейчас воспринимайте это как модель данных для экспериментов. Обратите внимание: публичные свойства Name и Age — важны для сериализации, а для XmlSerializer нужен публичный конструктор без параметров.

2. Сериализация в JSON с помощью System.Text.Json

Простейший пример

Обещали — показываем! Вот как выглядит сериализация в JSON:

using System;
using System.Text.Json;

Person person = new Person("Алиса", 28);

// Сериализация: превращаем объект в JSON-строку
string json = JsonSerializer.Serialize(person);

Console.WriteLine("JSON:");
Console.WriteLine(json);

Что будет на экране?

JSON:
{"Name":"Алиса","Age":28}

Всё просто: объект → JSON. Вот она, магия!

Десериализация — возвращаем всё обратно

Теперь сделаем обратную операцию — из JSON-строки восстановим объект:

string json = "{\"Name\":\"Боб\",\"Age\":35}";

// Десериализация: восстанавливаем объект типа Person из строки JSON
Person restored = JsonSerializer.Deserialize<Person>(json);

Console.WriteLine("Восстановленный объект:");
Console.WriteLine($"Имя: {restored.Name}, возраст: {restored.Age}");

Результат:

Восстановленный объект:
Имя: Боб, возраст: 35

Обратите внимание: если структура данных не совпадает (например, нет такого свойства), соответствующее поле останется со значением по умолчанию (null для ссылочных типов, 0 для чисел и т.п.).

3. Сериализация/десериализация в XML с помощью XmlSerializer

Сериализация в XML — первый взгляд

using System;
using System.IO;
using System.Xml.Serialization;

Person person = new Person("Катя", 22);

// Создаем сериализатор для типа Person
var serializer = new XmlSerializer(typeof(Person));

// Записываем XML в файл
using (var stream = new FileStream("person.xml", FileMode.Create))
{
    serializer.Serialize(stream, person);
    // Поток автоматически закроется в конце using-блока
}
Console.WriteLine("XML-файл создан!");

В файле person.xml появится что-то вроде такого:

<?xml version="1.0"?>
<Person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Name>Катя</Name>
  <Age>22</Age>
</Person>

Важный момент:
Для сериализации в файл используется поток (Stream, например, FileStream). Если вы хотите сериализовать в строку (например, для отправки по сети), используйте StringWriter:

var serializer = new XmlSerializer(typeof(Person));
using (var sw = new StringWriter())
{
    serializer.Serialize(sw, person);
    string xmlString = sw.ToString();
    Console.WriteLine(xmlString);
}

Десериализация из XML

using (var stream = new FileStream("person.xml", FileMode.Open))
{
    // Не забудьте привести к нужному типу!
    Person restored = (Person)serializer.Deserialize(stream);
    Console.WriteLine($"Имя: {restored.Name}, возраст: {restored.Age}");
}

Ещё раз: XmlSerializer требует, чтобы у сериализуемого класса был публичный конструктор по умолчанию (без параметров).

4. Работа с файлами и строками: что выбрать?

В реальной жизни сериализация может идти сразу в строку (для передачи по сети/хранения в БД) или в файл (для длительного хранения).

Сериализация в строку (например, для передачи через API):

  • JSON: используем JsonSerializer.Serialize(obj).
  • XML: через StringWriter.

Сериализация в файл (например, для экспорта/резервной копии):

  • JSON: сохраняем строку в файл обычными средствами записи файлов.
  • XML: напрямую пишем в поток с помощью XmlSerializer.

Пример: сериализация в файл и обратно (JSON)

using System.IO;
using System.Text.Json;

Person person = new Person("Том", 42);

// Сериализация в строку
string json = JsonSerializer.Serialize(person);

// Запись в файл
File.WriteAllText("contact.json", json);

// Чтение из файла
string readJson = File.ReadAllText("contact.json");
Person restored = JsonSerializer.Deserialize<Person>(readJson);

Console.WriteLine($"{restored.Name}, возраст: {restored.Age}");

5. Сравнение JSON vs XML

Визуализация процесса

Чтобы не запутаться, вот схема процесса сериализации и десериализации:

flowchart LR
    A[Объект] -- сериализация --> B[Строка/Файл/Поток]
    B -- десериализация --> C[Объект]

    A -. JSON или XML .-> B
    B -. JSON или XML .-> C

Можете представить, что сериализация — это «упаковать чемодан», а десериализация — «распаковать» дома.

Таблица сравнения

Функциональность JSON (System.Text.Json) XML (XmlSerializer)
Чтение/запись в строку ++ +
Чтение/запись в файл ++ ++
Требует конструктор без параметров Нет Да
Читабельность для человека ++ +
Строгая схема данных (валидация) - ++
Гибкость (атрибуты кастомизации) + ++
Производительность ++ +
Совместимость с интернетом ++ +

++ — очень хорошо, + — нормально, - — не поддерживается

6. Как добавить сериализацию в наше приложение

Пусть в «Менеджере контактов» появилась возможность сохранять список контактов пользователей в файл и восстанавливать его.

Контекст: у нас есть список контактов (List<Person>).

List<Person> contacts = new List<Person>
{
    new Person("Вася", 30),
    new Person("Петя", 25),
    new Person("Маша", 27)
};

// Сохраняем все контакты — сериализуем в JSON
string jsonContacts = JsonSerializer.Serialize(contacts);
File.WriteAllText("contacts.json", jsonContacts);

// Восстанавливаем список контактов
string readContactsJson = File.ReadAllText("contacts.json");
List<Person> restored = JsonSerializer.Deserialize<List<Person>>(readContactsJson);

foreach (var c in restored)
{
    Console.WriteLine($"{c.Name}, возраст: {c.Age}");
}

То же самое можно сделать и с XML, но там есть особенности. Для сериализации коллекций через XmlSerializer обычно оборачивают список в отдельный класс-контейнер (корневой элемент) — так проще контролировать формат и имена элементов.

7. Типичные ошибки при сериализации и десериализации

Ошибка №1: несовпадение типов при сериализации и десериализации.
Сериализовали List<Person> — десериализовать нужно тоже в List<Person>, а не в List<object> или IEnumerable<Person>. Иначе получите ошибку или неожиданные результаты.

Ошибка №2: попытка сериализовать непубличные поля и свойства.
Типичные сериализаторы (JsonSerializer, XmlSerializer) работают с публичными членами. Если у свойства нет публичного геттера/сеттера, значение может не попасть в JSON/XML, и вы будете искать, почему там null.

Ошибка №3: отсутствие конструктора без параметров.
Для XmlSerializer публичный конструктор по умолчанию обязателен. Если его нет — будет исключение при десериализации.

Ошибка №4: неправильное понимание ссылок на объекты.
Если один объект содержит ссылку на другой, сериализация идёт «по значению» (как вложенный объект). Ссылки как таковые не сохраняются, что может привести к дублированию данных или проблемам с циклическими ссылками.

Ошибка №5: попытка смешивать форматы сериализации.
XML и JSON — разные форматы и сериализаторы. Нельзя передать JSON-строку в XmlSerializer и наоборот — будет ошибка.

2
Задача
C# SELF, 45 уровень, 0 лекция
Недоступна
Сериализация и десериализация объекта в JSON
Сериализация и десериализация объекта в JSON
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ