99 votes

DataContractSerializer n'appelle pas mon constructeur?

Je viens de réaliser quelque chose de fou, que je suppose être tout à fait impossible : lors de la désérialisation d'un objet, le DataContractSerializer n'appelle pas le constructeur !

Prendre cette classe, par exemple :

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

Quand je désérialiser un objet de cette classe, le point d'arrêt n'est pas atteint. Je n'ai absolument aucune idée de comment il est possible, puisque c'est le seul constructeur pour cet objet !

Je suppose que peut-être un supplément de constructeur a été généré par le compilateur en raison de l' DataContract d'attribut, mais je ne pouvais pas le trouver, grâce à la réflexion...

Donc, ce que j'aimerais savoir, c'est ceci : comment pourrait-d'une instance de ma classe est créé sans le constructeur appelée ??

NOTE: je sais que je peux utiliser l' OnDeserializing d'attribut pour initialiser mon objet lors de la désérialisation commence, ce n'est pas l'objet de ma question.

135voto

Marc Gravell Points 482669

DataContractSerializer (comme BinaryFormatter ) n'utilise aucun constructeur. Il crée l'objet en tant que mémoire vide.

Par exemple:

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

L'hypothèse est que le processus de désérialisation (ou des rappels si nécessaire) l'initialisera complètement.

3voto

BasvdL Points 64

Il y a quelques scénarios qui ne serait pas possible sans ce comportement. Pensez à ce qui suit:

1) Vous avez un objet qui possède un constructeur qui définit la nouvelle instance d'un "initialisé" de l'état. Ensuite, certaines méthodes sont appelées à l'instance, que de le mettre dans un "traité" de l'état. Vous ne voulez pas créer de nouveaux objets ayant le "traitement" de l'état, mais vous voulez toujours de sérialiser / désérialiser l'instance.

2) Vous avez créé une classe avec un constructeur privé et certaines propriétés statiques pour le contrôle d'un petit ensemble de paramètres du constructeur. Maintenant, vous pouvez toujours sérialiser / désérialiser.

XmlSerializer a le comportement attendu. J'ai eu quelques problèmes avec le XmlSerializer parce qu'il N'a besoin d'un constructeur par défaut. Par rapport à cela, parfois, il est logique d'avoir la propriété privée des poseurs. Mais le XmlSerializer également les besoins du public getter et setter sur les propriétés afin de sérialiser / désérialiser.

Je pense que le DataContractSerializer / BinaryFormatter comportement comme la suspension de l'état d'une instance au cours de la sérialisation et la reprise lors de la désérialisation. En d'autres termes, les instances ne sont pas "construit", mais "restauré" à un état antérieur.

Comme vous l'avez déjà mentionné, l' [OnDeserializing] attribut permet de garder les données sérialisées dans la synchronisation.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X