На заметку!
Применение типаBinaryFormatter (https://docs.microsoft.com/ru-ru/dotnet/api/system.runtime.serialization.formatters.binary.binaryformatter?view=net-5.0), который рассматривался в предшествующих изданиях книги, сопряжено с высоким риском в плане безопасности, так что от него следует немедленно отказаться. Более защищенные альтернативы предусматривают использование классов BinaryReader/BinaryWriter для XML/JSON.Сериализация объектов .NET Core упрощает сохранение объектов, но ее внутренний процесс довольно сложен. Например, когда объект сохраняется в потоке, все ассоциированные с ним открытые данные (т.е. данные базового класса и содержащиеся в нем объекты) также автоматически сериализируются. Следовательно, при попытке сериализации производного класса в игру вступают также все открытые данные по цепочке наследования. Вы увидите, что для представления множества взаимосвязанных объектов используется граф объектов.
Наконец, имейте в виду, что граф объектов может быть сохранен в любом типе, производном от System.IO.Stream
Роль графов объектов
Как упоминалось ранее, среда CLR будет учитывать все связанные объекты, чтобы обеспечить корректное сохранение данных, когда объект сериализируется. Такой набор связанных объектов называется
Каждый объект в графе получает уникальное числовое значение. Важно помнить, что числа, присвоенные объектам в графе, являются произвольными и не имеют никакого смысла для внешнего мира. После того как всем объектам назначены числовые значения, граф объектов может записывать набор зависимостей для каждого объекта.
В качестве примера предположим, что создано множество классов, которые моделируют автомобили. Существует базовый класс по имени Car
Radio. Другой класс по имени JamesBondCar расширяет базовый тип Car.На рис. 20.1 показан возможный граф объектов, моделирующий такие отношения. При чтении графов объектов для описания соединяющих стрелок можно использовать выражение "зависит от" или "ссылается на". Таким образом, на рис. 20.1 видно, что класс Car
Radio (учитывая отношение "имеет" ), JamesBondCar ссылается на Car (из-за отношения "является" ), а также на Radio (поскольку наследует эту защищенную переменную-член).Разумеется, исполняющая среда не рисует картинки в памяти для представления графа связанных объектов. Взамен отношение, показанное на рис. 20.1, представляется математической формулой, которая выглядит следующим образом:
[Car 3, ref 2], [Radio 2], [JamesBondCar 1, ref 3, ref 2]
Проанализировав формулу, вы заметите, что объект 3 (Car
Radio). Объект 2 (Radio) — "одинокий волк", которому никто не нужен. Наконец, объект 1 (JamesBondCar) имеет зависимость от объекта 3, а также от объекта 2. В любом случае при сериализации или десериализации экземпляра JamesBondCar граф объектов гарантирует, что типы Radio и Car тоже примут участие в процессе.Привлекательность процесса сериализации заключается в том, что граф, представляющий отношения между объектами, устанавливается автоматически "за кулисами". Как будет показано позже в главе, при желании в конструирование графа объектов можно вмешиваться, настраивая процесс сериализации с применением атрибутов и интерфейсов.
Создание примеров типов и написание операторов верхнего уровня
Создайте новый проект консольного приложения .NET 5 по имени SimpleSerialize
Radio.cs со следующим кодом:using System;
using System.Linq;
using System.Collections.Generic;
using System.Text.Json.Serialization;
using System.Xml;
using System.Xml.Serialization;
namespace SimpleSerialize
{
public class Radio
{
public bool HasTweeters;
public bool HasSubWoofers;
public List
public string RadioId = "XF-552RR6";
public override string ToString()
{