2012-09-08 5 views
2

Puis-je éviter d'ajouter des champs supplémentaires à une classe pour stocker des données qui est nécessaire uniquement pour désérialisation/sérialisation?Où stocker les meilleures données de désérialisation temporaire?

Supposons que j'ai une classe:

[Serializable] 
class MyClass { 
     [NonSerialized] 
     NonSerializableDataType myField; 

     SomeOtherDataType serializableTemporaryData; 

     [OnSerializing] 
     OnSerializing (StreamingContext context) { 
      // build serializableTemporaryData from myField 
     } 

     [OnDeserialized] 
     void OnDeserialized (StreamingContext context) { 
     // build myField from serializableTemporaryData 
     } 
} 

Est-il possible d'éviter d'avoir le champ serializableTemporaryData dans chaque objet de MyClass? Puis-je, par exemple, le rendre statique (éventuellement en changeant mes méthodes On ...)?

Constraint: Je ne peux pas changer la mise en œuvre de NonSerializableDataType.

Exemple: Supposons myField contient une poignée à une ressource. Ensuite, lors de la sérialisation, je dois stocker des informations sur la façon d'acquérir la ressource après la sérialisation, mais je ne peux pas stocker la poignée elle-même. Si je place le handle dans une autre classe, alors je viens de déplacer le problème vers la classe wrapper - je poserais alors la même question pour la classe wrapper.

+1

Faire statique est une mauvaise idée ici. Considérons deux threads agissant sur deux objets de même classe, faisant la sérialisation. – Ankush

+0

Quel sérialiseur utilisez-vous? Xml ou binaire? De plus, vous ne pouvez pas changer 'NonSerializableDataType', mais pouvez-vous en hériter? –

+0

Pourquoi avez-vous besoin de stocker et ne pouvez pas le produire à chaque fois? – MichaelT

Répondre

5

Si vous avez besoin de contrôler le processus de sérialisation, vous devez implémenter l'interface ISerialization.

[Serializable] 
public class MyClass: ISerializable 
{ 
    // As you are in control of serialization process now 
    // [Serialized] and [NonSerialized] attributes are no longer required 
    private NonSerializableDataType myField; 

    public virtual void GetObjectData(SerializationInfo info, StreamingContext context) 
    { 
     // Create and populate your SomeOtherDataType local variable here, then push it into info variable 
     // Or even better, dont create SomeOtherDataType, just put additional serialization data into info variable, for example: 
     info.AddValue("URL", "http://this.way.com"); 
    } 

    protected MyClass(SerializationInfo info, StreamingContext context) 
    { 
     // Dont forget to define constructor for deserialization purpose 

     this.myField = new NonSerializableDataType(loadFromURL: (string)info.GetValue("URL", typeof(string))); 
    } 
} 

Aucune classe supplémentaire uniquement pour les données de sérialisation, pas de pollution des champs. Le seul problème potentiel est de surveiller les données sérialisables dérivées de cette classe (remplacer GetObjectData(...) si nécessaire).

Plus d'info: MSDN ISerializable

+0

Merci. Cela semble être ce dont j'ai besoin. – JohnB

3

Il y a un concept de serialization surrogates qui pourrait vous aider à surmonter la difficulté avec SomeNonSerializableType, car il a été conçu exactement pour cette raison .. Cependant, cela suppose que vous avez la possibilité de configurer les substituts de sérialisation, lorsque le formateur est créé. Sinon, vous devrez personnaliser le processus de sérialisation en implémentant ISerializable.

+0

Merci pour le lien et l'indice pour les substituts. Je vais travailler à travers cela. – JohnB

Questions connexes