# Programmation C sharp/La sérialisation

La sérialisation est un procédé d'entrée-sortie permettant de sauvegarder et recharger l'état d'un objet. Cette fonctionnalité permet de faire abstraction du format de fichier utilisé. Celui-ci dépend de l'outil de sérialisation utilisé.
L'état d'un objet correspond à l'ensemble des valeurs de ses champs. Les propriétés sont calculées en fonction des champs, et le code des méthodes ne change pas au cours de l'exécution.

## Attributs

L'attribut System.SerializableAttribute marque les classes dont les instances peuvent être sérialisées. Si l'attribut est absent pour une classe, la sérialisation de ses instances provoquera une exception.
Exemple :
L'attribut System.NonSerializedAttribute marque les champs qu'il ne faut pas enregistrer. C'est le cas des champs dont on peut retrouver la valeur par calcul, par exemple.
Exemple :
Quand la classe évolue, de nouveaux champs sont ajoutés à la classe, d'autres sont retirés. L'attribut System.Runtime.Serialization.OptionalFieldAttribute marque les champs optionnels lors de la désérialisation (lecture de l'objet). Il est donc possible de marquer les nouveaux champs comme optionnels, et garder les anciens champs (marqués optionnels également) pour garder la compatibilité avec les anciens fichiers.
Exemple :
Dans cet exemple, la classe Facture permettra de lire des fichiers d'objets Facture contenant le champ AdresseLivraison ou non.

## La sérialisation

Le format de sérialisation dépend de la classe utilisée pour sérialiser les objets.

### La classe System.Runtime.Serialization.Formatter

Cette classe abstraite définit les méthodes suivantes :
    Cette méthode enregistre l'objet graph dans le flux d'entrée-sortie spécifié.
    Cette méthode retourne l'objet lu depuis le flux d'entrée-sortie spécifié.
Les classes dérivées définissent un format concret de sérialisation :
* La classe System.Runtime.Serialization.Formatters.Binary.BinaryFormatter permet de sérialiser dans un format binaire,
* La classe System.Runtime.Serialization.Formatters.Soap.SoapFormatter permet de sérialiser au format SOAP.
Une classe dérivée de System.Runtime.Serialization.Formatter sérialise les attributs et les évènements d'un objet, quel que soit l'accès associé (public, protégé, privé, ou par défaut).

### Format XML

La classe System.Xml.Serialization.XmlSerializer permet de sérialiser au format XML. Elle ne dérive pas de la classe System.Runtime.Serialization.Formatter, et possède les méthodes suivantes :
    Ces méthodes enregistrent l'objet o dans le flux d'entrée-sortie spécifié.
    Ces méthodes retournent l'objet lu depuis le flux d'entrée-sortie spécifié.
Pour le format XML, les attributs Serializable et NonSerialized sont ignorés :
* Toute classe est sérialisable en XML,
* L'attribut System.Xml.Serialization.XmlIgnoreAttribute marque les champs à ignorer lors de la sérialisation.
La classe System.Xml.Serialization.XmlSerializer sérialise les attributs et les propriétés en lecture/écriture publics d'un objet, si la valeur n'est pas nulle. Donc la sérialisation en XML ignore :
* les attributs et propriétés retournant une valeur nulle,
* les attributs et propriétés protégés ou privés,
* les propriétés en lecture seule (impossible de les désérialiser),
* les propriétés en écriture seule (impossible de les sérialiser).
Pour en savoir plus :
* (anglais) XML Serialization in the .NET Framework

## Sérialisation personnalisée

Il est possible de personnaliser la manière de sérialiser un objet en implémentant l'interface System.Runtime.Serialization.ISerializable.
Cette interface n'a qu'une méthode, invoquée lors de la sérialisation :
Mais la classe doit également comporter le constructeur suivant, invoqué lors de la désérialisation :
L'objet de type SerializationInfo permet la sérialisation et la désérialisation de l'objet. Chaque valeur sauvegardée est associé à un nom unique. Cet objet possède les méthodes suivantes :
L'implémentation de la méthode GetObjectData fait appel à la méthode AddValue de l'objet info pour ajouter une valeur à sauvegarder. Le constructeur utilise la méthode GetValue ou les méthodes GetType pour retrouver la valeur sauvegardée.
Exemple :