DataContractSerializer не вызывает мой конструктор?

Я только что понял что-то сумасшедшее, что я предполагал совершенно невозможным: при десериализации объекта DataContractSerializer не вызывает конструктор!

Возьмите этот класс, например:

[DataContract]
public class Book
{
    public Book()
    { // breakpoint here
    }

    [DataMember(Order = 0)]
    public string Title { get; set; }
    [DataMember(Order = 1)]
    public string Author { get; set; }
    [DataMember(Order = 2)]
    public string Summary { get; set; }
}

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

Я предположил, что, возможно, дополнительный компилятор был создан компилятором из-за атрибута DataContract, но я не смог найти его через отражение...

Итак, мне хотелось бы знать следующее: как создать экземпляр моего класса без вызова конструктора

ПРИМЕЧАНИЕ. Я знаю, что я могу использовать атрибут OnDeserializing для инициализации моего объекта при начале десериализации, это не вопрос моего вопроса.

Ответ 1

DataContractSerializer (например, BinaryFormatter) не использует конструктор any. Он создает объект как пустую память.

Например:

    Type type = typeof(Customer);
    object obj = System.Runtime.Serialization.
        FormatterServices.GetUninitializedObject(type);

Предполагается, что процесс десериализации (или обратный вызов при необходимости) полностью инициализирует его.

Ответ 2

Есть некоторые сценарии, которые не были бы возможны без такого поведения. Подумайте о следующем:

1) У вас есть объект, у которого есть один конструктор, который устанавливает новый экземпляр в "инициализированное" состояние. Затем в этот экземпляр вызываются некоторые методы, которые приводят его в "обработанное" состояние. Вы не хотите создавать новые объекты, имеющие "обработанное" состояние, но вы все же хотите сериализовать/десериализовать экземпляр.

2) Вы создали класс с частным конструктором и некоторые статические свойства для управления небольшим набором разрешенных параметров конструктора. Теперь вы все еще можете сериализовать/десериализовать их.

XmlSerializer имеет поведение, которое вы ожидали. У меня были некоторые проблемы с XmlSerializer, потому что для этого нужен конструктор по умолчанию. В связи с этим иногда имеет смысл иметь частные сеттеры. Но XmlSerializer также нуждается в публичном getter и setter на свойствах для сериализации/десериализации.

Я думаю о поведении DataContractSerializer/BinaryFormatter, как о приостановке состояния экземпляра во время сериализации и возобновлении во время десериализации. Другими словами, экземпляры не "построены", а "восстановлены" в более раннем состоянии.

Как уже упоминалось, атрибут [OnDeserializing] позволяет синхронизировать несериализованные данные.