Как сериализация работает в .Net

У меня такое чувство, что это репост, но я не могу найти о нем никакой хорошей информации. Мне просто было интересно, как на самом деле работает сериализация (ну, на самом деле десериализация). Мне интересно, если, скажем, у меня есть свойство, которое на самом деле не поддерживается частным полем; то есть:

public string SomeProp {
   get {
      return GetValue("SomePropKey");
   }
   set{
      SetValue("SomePropKey", value);
   }
}

Когда я десериализую, вызывается ли сеттер? Получатель вызывается при сериализации, потому что, когда я сериализую объект, правильное значение записывается в выходной поток. Я знаю, что это кажется странным обстоятельством, но что происходит на самом деле? Или я просто слишком усложняю это ....

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
6
0
1 160
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Это полностью зависит от механизма, который вы используете для сериализации.

Если вы используете XmlSerialization, то да, вызывается установщик.

Если вы используете сериализацию контракта данных (DataContractSerialization), то метод получения / установки будет вызываться, если вы примените атрибут DataMember к свойству (а не к его поддерживающему полю).

Если вы используете исходный механизм сериализации в .NET (реализация IFormatter), этот сценарий невозможен, потому что он будет сериализовать только значения, хранящиеся в полях.

Спасибо, мы используем XmlSerialization. Извините, я не включил это. И еще раз спасибо!

Adam Driscoll 21.01.2009 22:32

XmlSerializer сериализует общедоступные члены и вызывает конструктор с нулевым параметром, что раздражает, поскольку предполагает, что то, что вы хотите, чтобы ваша бизнес-логика выполняла при построении, идентично тому, что вы хотите при десериализации. Это может быть верно для 99% ваших классов, и этого недостаточно. BinaryFormatter.Serialize (и, вероятно, SoapFormatter.Serialize) доказывают, что это ограничение не нужно и его можно избежать, а также они не требуют от вас увеличения риска, поскольку частные члены сериализуемы. К сожалению, BinaryFormatter и SoapFormatter устарели.

H2ONaCl 12.03.2021 18:25

BinaryFormatter считается угрозой безопасности. На мой взгляд, DataContractSerializer лучше, чем XmlSerializer. Конструктор с нулевым параметром не имеет ограничений, поэтому кодируйте его по своему усмотрению. Это меньший риск, потому что данные могут быть конфиденциальными; люди, смотрящие на сериализованные файлы XML, не выдерживают. Атрибуты DataContract / DataMember раздражают, но приемлемы.

H2ONaCl 12.03.2021 18:35

Оформление DataMember в поле set / get означает, что аксессоры будут запускаться при сериализации / десериализации. Я предпочитаю размещать украшение DataMember в резервном хранилище, потому что я не предполагаю, что бизнес-логика set / get всегда будет актуальна для сериализации / десериализации, и решение, что это актуально, похоже на увековечение ограничения. Нет необходимости помещать атрибут DataMember как в резервное хранилище, так и в свойство, которое может быть недокументировано, потому что это очевидно, или оно может быть недокументированным, потому что документация не доработана.

H2ONaCl 12.03.2021 18:54

Еще проблемы с XmlSerializer: он не может сериализовать словарь. Если ваш класс реализует IEnumerable <T>, тогда XmlSerializer будет рассматривать объект, как если бы он был не чем иным, как перечислимым, и игнорировал данные других членов, а не сериализовал их.

H2ONaCl 13.03.2021 02:03

Вы говорите о сериализации XML или «обычной» сериализации (мыльной / двоичной), поскольку -afaik- эти 2 метода сериализации различаются.

AFAIK, если вы используете BinaryFormatter или SoapFormatter, поля сериализуются / десериализуются, а не свойства. Что касается десериализации, я считаю, что используется специальный конструктор с двумя аргументами, который имеет аргументы SerializationInfo и StreamingContext.

Но ничто не мешает вам взять под контроль процесс сериализации, реализовав интерфейс ISerializable. Затем, если вы хотите, чтобы ваше значение было установлено с использованием вашего свойства, я думаю, вы отлично это сделаете.

Я знаю, что это не прямой ответ на ваш вопрос, и вы уже получили ответ, который искали. Но я не хотел скрывать это. Вы можете посмотреть исходники библиотеки базовых классов, используя Отражатель. Это отличный способ лучше понять внутреннее устройство .NET Framework и расширить свои знания.

Другие вопросы по теме