Сериализация объектов в C# (.NET): от основ до продвинутых техник
Сериализация — это процесс преобразования сложных объектов (классов, структур) в формат, который можно сохранить в файл, передать по сети или записать в базу данных. Обратный процесс (восстановление объекта из потока данных) называется десериализацией. В платформе .NET существует несколько встроенных и сторонних инструментов для сериализации, каждый со своими особенностями, производительностью и областью применения.
В этой статье мы разберём основные способы сериализации в C#: JSON (System.Text.Json и Newtonsoft.Json), XML (XmlSerializer), бинарную сериализацию (BinaryFormatter — устаревший, но всё ещё встречается) и Protocol Buffers (protobuf-net) для высокопроизводительных сценариев.
1. Сериализация в JSON с System.Text.Json
Начиная с .NET Core 3.0, Microsoft рекомендует использовать пространство имён System.Text.Json для работы с JSON. Это быстрый, низкоуровневый и асинхронный API.
Пример сериализации и десериализации:
using System;
using System.Text.Json;
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public string Email { get; set; }
}
class Program
{
static void Main()
{
var person = new Person
{
Name = "Иван Петров",
Age = 30,
Email = "ivan@example.com"
};
// Сериализация в строку JSON
string jsonString = JsonSerializer.Serialize(person);
Console.WriteLine(jsonString);
// Вывод: {"Name":"Иван Петров","Age":30,"Email":"ivan@example.com"}
// Десериализация из JSON
string jsonInput = @"{""Name"":""Мария"",""Age"":25,""Email"":""maria@test.ru""}";
Person restoredPerson = JsonSerializer.Deserialize<Person>(jsonInput);
Console.WriteLine($"Имя: {restoredPerson.Name}, Возраст: {restoredPerson.Age}");
}
}
Настройка сериализации:
- Игнорирование null-свойств:
JsonSerializerOptions { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull } - Форматирование (pretty print):
JsonSerializerOptions { WriteIndented = true } - Работа с циклическими ссылками:
ReferenceHandler.Preserve
2. Newtonsoft.Json (Json.NET) — классика
До появления System.Text.Json стандартом де-факто была библиотека Newtonsoft.Json (устанавливается через NuGet). Она поддерживает больше сценариев: динамические объекты, атрибуты, конвертеры и гибкие настройки.
using Newtonsoft.Json;
public class Order
{
public int Id { get; set; }
public decimal Amount { get; set; }
[JsonIgnore]
public string InternalNote { get; set; } // Это поле не будет сериализовано
}
var order = new Order { Id = 1, Amount = 99.99m, InternalNote = "Секретно" };
string json = JsonConvert.SerializeObject(order, Formatting.Indented);
Console.WriteLine(json);
// {
// "Id": 1,
// "Amount": 99.99
// }
var deserialized = JsonConvert.DeserializeObject<Order>(json);
3. Сериализация в XML (XmlSerializer)
Для XML-формата в .NET используется класс XmlSerializer. Он хорошо подходит для совместимости с устаревшими системами и SOAP-сервисами.
using System;
using System.IO;
using System.Xml.Serialization;
[Serializable]
public class Product
{
[XmlAttribute]
public int Id { get; set; }
[XmlElement("ProductName")]
public string Name { get; set; }
}
class Program
{
static void Main()
{
var product = new Product { Id = 42, Name = "Ноутбук" };
// Сериализация в файл
XmlSerializer serializer = new XmlSerializer(typeof(Product));
using (FileStream fs = new FileStream("product.xml", FileMode.Create))
{
serializer.Serialize(fs, product);
}
// Десериализация из файла
using (FileStream fs = new FileStream("product.xml", FileMode.Open))
{
Product loaded = (Product)serializer.Deserialize(fs);
Console.WriteLine($"{loaded.Id}: {loaded.Name}");
}
}
}
Важно: XmlSerializer требует, чтобы класс имел конструктор без параметров. Атрибуты [XmlAttribute] и [XmlElement] позволяют управлять структурой XML.
4. Бинарная сериализация (BinaryFormatter) — устаревший подход
Раньше для быстрой сериализации в .NET Framework использовался BinaryFormatter. Однако с выходом .NET 5 он помечен как опасный (из-за уяз