DataContractSerializer não chama meu construtor?

Acabei de perceber algo louco, que eu assumi ser completamente impossível: ao desserializar um object, o DataContractSerializer não chama o construtor !

Tome esta class, por exemplo:

[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; } } 

Quando eu desserializo um object dessa class, o ponto de interrupção não é atingido. Eu não tenho absolutamente nenhuma idéia de como isso é possível, já que é o único construtor para este object!

Eu assumi que talvez um construtor adicional tenha sido gerado pelo compilador por causa do atributo DataContract , mas não consegui encontrá-lo através da reflection …

Então, o que eu gostaria de saber é isto: como poderia uma instância da minha class ser criada sem que o construtor fosse chamado ??

NOTA: Eu sei que posso usar o atributo OnDeserializing para inicializar meu object quando a desserialização é iniciada, esse não é o assunto da minha pergunta.

DataContractSerializer (como BinaryFormatter ) não usa nenhum construtor. Cria o object como memory vazia.

Por exemplo:

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

A suposição é que o processo de desserialização (ou callbacks, se necessário) será totalmente inicializado.

Existem alguns cenários que não seriam possíveis sem esse comportamento. Pense no seguinte:

1) Você tem um object que possui um construtor que define a nova instância para um estado “inicializado”. Em seguida, alguns methods são chamados nessa instância, que a trazem em um estado “processado”. Você não deseja criar novos objects com o estado “processado”, mas ainda deseja serializar / desserializar a instância.

2) Você criou uma class com um construtor privado e algumas propriedades estáticas para controlar um pequeno conjunto de parâmetros permitidos do construtor. Agora você ainda pode serializá-los / desserializá-los.

XmlSerializer tem o comportamento esperado. Eu tive alguns problemas com o XmlSerializer porque ele precisa de um construtor padrão. Relacionado a isso, às vezes faz sentido ter setters de propriedade privada. Mas o XmlSerializer também precisa getter e setter público em propriedades para serializar / desserializar.

Penso no comportamento de DataContractSerializer / BinaryFormatter como suspender o estado de uma instância durante a serialização e retomar durante a desserialização. Em outras palavras, as instâncias não são “construídas”, mas “restauradas” para um estado anterior.

Como você já mencionou, o atributo [OnDeserializing] possibilita manter dados não serializados em sincronia.