.NET Deserialisation avec OnDeserializing et OnDeserialized
J'utilise une classe simple qui est sérialisable. Il a un constructeur pour la désérialisation:
protected MyClass(SerializationInfo info, StreamingContext context)
et un GetObjectData méthode de sérialisation. Il fonctionne très bien.
Maintenant, j'ai ajouté deux méthodes de suivi de la deserialisation:
[OnDeserializing()]
internal void OnDeserializingMethod(StreamingContext context)
{
System.Diagnostics.Trace.WriteLine("OnDeserializingMethod: " + this.GetType().ToString());
}
[OnDeserialized()]
internal void OnDeserializedMethod(StreamingContext context)
{
System.Diagnostics.Trace.WriteLine("OnDeserializedMethod: " + this.GetType().ToString());
}
et je me demandais dans quel ordre ces méthodes sont être appelé. Maintenant, les deux méthodes appelée avant que le constructeur est appelé. Comment est-ce possible, et pourquoi n'est-elle pas la "OnDeserialized" méthode appelée ainsi d'après le (la désérialisation-) constructeur a été appelé? Et comment un (non statique) de la méthode appelée avant tout constructeur a été exécuté? (Je suis à l'aide d'un BinaryFormatter)
OriginalL'auteur Gerhard | 2013-08-22
Vous devez vous connecter pour publier un commentaire.
Pas, la commande est:
Parce qu'il triche et le mensonge; il n'a pas créer l'objet avec le constructeur; pas - vraiment. Il utilise
FormatterServices.GetUninitializedObject
d'allouer à la vanille vide de l'espace. Et puis si il y a une coutume de la désérialisation constructeur qu'il appelle le constructeur au-dessus de ce objet. De méchant. Comme ça, en fait:De l'OMI, ils devraient probablement en ont fait un deuxième méthode sur la
ISerializable
de l'interface, mais pour quelque raison que ce soit: ils n'ont pas. Une honte vraiment: qu'il aurait été plus honnête, et d'éviter les personnes ayant besoin de se rappeler de mettre en œuvre le constructeur personnalisé.Exemple de sortie:
Exemple de code:
Merci, préfet réponse, je vais le marquer comme acceptée qu'après j'ai trouvé pourquoi, dans mon scénario, le ctor est appelé en dernier. Peut-être parce que l'objet n'est pas à la racine de la sérialisée de l'arbre.
OK Marc, votre réponse est correcte uniquement pour l'objet racine. Voir ma réponse ci-dessous pour des scénarios plus complexes. Aucune idée de pourquoi il se comporte comme ça? Par la route: très cool [CallerMemberName] Attribut! Je ne savais pas qu'avant (mais seulement .NET 4.5)
OriginalL'auteur Marc Gravell
L'ordre des appels dépend si l'objet est à la racine de la sérialisé arbre ou quelque membre d'un objet, qui est également publié en feuilleton dans le même objet graphique. J'obtiens le résultat suivant avec l'exemple fourni par Marc Gravel:
Avis que, dans la désérialisation SerMember.ctor est appelée après SerMember.OnDeserializedMethod! C'est le code:
IDeserializationCallback
, qui est appelé à l'heure correcte.Ce " bug " a été me causer beaucoup de chagrin. Bonne prise. @Marc: à l'Aide de IDeserializationCallback n'est pas toujours une solution. Certains sérialise ne le supporte pas car il n'est pas portable (par ex. Json.NET voir ici). Dirait qu'il y a pas de solution autre que d'éviter la ISerializable des objets au-delà de l'objet racine dans le graphique.
OriginalL'auteur Gerhard
[OnDeserializing]
Indique une méthode pour être appelé juste avant la désérialisation
[OnDeserialized]
Indique une méthode pour être appelé juste après la désérialisation
[OnDeserializing] méthode agit comme un pseudoconstructor pour la désérialisation, et
il est utile pour initialiser les champs exclus de la sérialisation:
[OnDeserializing] et [OnDeserialized]
La désérialisation contourne tous vos normale constructeurs sur le terrain ainsi que les initialiseurs.
C'est de peu de conséquence si tous les champs participe à la sérialisation, mais il peut être
problématique si certains domaines sont exclus par [NonSerialized].
J'ai pris ce texte de Albahari livre C# 5.0 en bref page 713 vérifier en ligne beaucoup d'exemple et
description de votre problème.
Grâce
Il suffit d'invoquer la méthode désirée sur OnDeserializingMethod!
OriginalL'auteur Bassam Alugili