1. Introduction
Imaginez que votre objet dans le programme — c'est une sorte de magnifique construction LEGO complexe. Il est composé de nombreuses pièces, chacune à sa place, et tout cela forme un ensemble. Tant que la construction est sur votre table (en mémoire du ordinateur), tout va bien. Mais que se passe-t-il si vous devez la transporter chez un ami (transmettre via le réseau), ou simplement la ranger dans une boîte pour la prochaine fois (sauvegarder sur disque) ? Vous ne pouvez pas simplement la mettre dans une boîte plate ! Elle se cassera !
C'est justement ce démontage soigné de l'objet en parties pour un stockage ou un transfert sûr qui s'appelle la sérialisation. C'est le processus de transformation de votre objet depuis son état "vivant" en mémoire en une séquence d'octets (ou une représentation textuelle) qu'on peut enregistrer dans un fichier, envoyer sur le réseau ou placer dans le presse-papiers. En gros, c'est comme démonter délicatement votre construction LEGO, mettre les pièces dans des sachets, les étiqueter et les emballer dans une boîte pour le transport ou le stockage.
flowchart LR
ObjectInMemory(Objet en mémoire)
Serialize[SÉRIALISATION]
BytesOrText[Octets / Fichier texte / JSON / XML]
Deserialize[DÉSÉRIALISATION]
ObjectAgain(Objet à nouveau en mémoire)
ObjectInMemory -->|serialize| Serialize
Serialize --> BytesOrText
BytesOrText -->|deserialize| Deserialize
Deserialize --> ObjectAgain
Et bien sûr, si on a emballé quelque chose, on doit savoir le déballer ! Le processus inverse s'appelle la désérialisation. C'est quand vous prenez cette boîte avec les sachets de pièces LEGO, vous les versez, puis, en suivant les instructions (ou en vous rappelant simplement comment c'était monté), vous reconstituez l'objet en mémoire dans exactement le même état qu'avant l'emballage. Voilà, magie !
Le terme « sérialisation » signifie littéralement « représentation séquentielle ». On prend une structure complexe, éventuellement dispersée en mémoire (un objet peut référencer d'autres objets, des collections, etc., formant un vrai « graphe d'objets ») et on la transforme en une forme linéaire et séquentielle, facile à écrire ou à transmettre.
2. Pourquoi File.WriteAllText ne suffit-il pas ?
Bonne question ! Si toutes les données étaient de simples chaînes ou chiffres, on pourrait se passer de sérialisation. Mais dans la réalité, nos applications manipulent des modèles complexes : clients, commandes, produits, étudiants, héros, niveaux. Ils sont tous représentés par des objets en mémoire. Voilà pourquoi la sérialisation est votre meilleur ami :
Sauvegarde de l'état de l'application
Imaginez que vous écrivez un éditeur de texte. L'utilisateur tape du texte, change les polices, insère des images. Toutes ces données (texte, paramètres, position du curseur) sont, en fait, des objets dans votre programme. Quand l'utilisateur clique sur "Enregistrer", vous voulez qu'au prochain lancement il retrouve tout exactement comme il l'a laissé. La sérialisation permet de "geler" tous les objets nécessaires et de les écrire sur le disque, puis de les "dégeler" au chargement. C'est comme la fonction "sauvegarder la partie" dans les jeux vidéo. Vous ne voulez pas refaire tout le niveau si l'électricité a été coupée, non ?
Échange de données entre applications
Votre programme en C# communique avec un serveur web qui peut être écrit en Python. Ou votre appli mobile (par exemple sur Xamarin ou MAUI) parle à un serveur sur .NET. Ces programmes n'ont pas de mémoire commune. Pour échanger des données, ils ont besoin d'un format commun et compréhensible. La sérialisation transforme les objets en ce format commun (par exemple JSON ou XML), qui peut être envoyé sur le réseau. De l'autre côté, le récepteur désérialise ces données en objets compréhensibles par leur langage. Sans sérialisation, il faudrait "dépaqueter" manuellement chaque morceau et le reconstituer. Ce serait long, ennuyeux et très sujet aux erreurs !
Imaginez que vous envoyez un colis à l'étranger. Vous ne pouvez pas juste envoyer vos affaires telles quelles ; vous devez les emballer dans un container (sérialisation) selon des standards internationaux. À l'arrivée, le destinataire pourra ouvrir ce container et récupérer ses affaires (désérialisation).
Configuration de l'application
Souvent, les applications ont beaucoup de réglages : taille de la fenêtre, chemin des fichiers, derniers documents ouverts, thème de couleurs. Stocker chaque réglage dans une variable séparée, puis les sauvegarder manuellement dans un fichier de config (par exemple .ini ou .txt) est inefficace et pénible. Il est beaucoup plus simple de définir une classe ParametresApplication, où chaque réglage est une propriété, puis de sérialiser cet objet de configuration entier dans un fichier. Au démarrage — désérialiser. Pratique !
Mise en cache des données
Parfois, récupérer des données (par exemple depuis une base ou un serveur distant) prend du temps. Pour ne pas refaire la requête à chaque fois, on peut récupérer une fois, sérialiser et stocker en cache (sur disque ou dans un stockage spécialisé). À la requête suivante, on vérifie d'abord le cache, et si les données y sont, on les désérialise. Ça accélère grandement l'application et réduit la charge sur les sources externes.
3. Idée principale : sauvegarder "l'état"
Le concept le plus important en sérialisation est la sauvegarde de l'état. Un objet est, en substance, la somme de ses champs et de leurs valeurs à un instant donné. La sérialisation "photographie" cet état. Quand on désérialise, on ne crée pas seulement un nouvel objet vide, on le recrée avec toutes les valeurs des champs qu'il avait au moment de la sérialisation.
Ce n'est pas juste copier des données. C'est une copie profonde de la structure et des valeurs, incluant les références à d'autres objets si le sérialiseur sait les gérer. Certains sérialiseurs peuvent même garder des informations sur le type de l'objet, ce qui permet de le désérialiser dans la bonne classe, même si au moment de la désérialisation on ne connaît pas le type exact à l'avance.
Exemple classique : sérialisation des animaux de compagnie
Poursuivons avec notre application « Encyclopédie des animaux de compagnie ». Supposons qu'on ait cette classe :
public class Pet
{
public string Name { get; set; }
public string Type { get; set; } // Par exemple : "Chat", "Chien"
public int Age { get; set; }
}
Nous voulons :
- Remplir une collection de tels objets en mémoire,
- La sauvegarder dans un fichier,
- Puis la restaurer plus tard (par exemple après relance du programme).
Schématiquement ça ressemble à ça :
Collection List<Pet>
↓ sérialisation
Fichier (JSON, XML, octets)
↓ désérialisation
Collection List<Pet> (à nouveau en mémoire!)
4. Quels sont les formats de sérialisation
Comme dans le transport, où il y a différents types de containers (boîtes en carton, caisses en bois, containers métalliques), en programmation il existe plusieurs formats de sérialisation. Chacun a ses particularités, avantages et inconvénients.
On n'entrera pas trop dans les détails pour l'instant, mais retenez quelques noms pour savoir de quoi on parlera dans les prochaines leçons :
- JSON (JavaScript Object Notation) : Aujourd'hui c'est sans doute le format le plus populaire. C'est textuel, relativement lisible par un humain et largement utilisé pour l'échange de données sur le web. Il ressemble à des paires "clé-valeur" encloses dans des accolades. En fait, c'est du texte structuré, facile à parser par des programmes.
- XML (Extensible Markup Language) : Plus ancien, mais toujours très répandu. C'est un format textuel basé sur des balises, comme HTML, avec une structure stricte. On l'utilise souvent pour des fichiers de configuration et l'échange de données dans des systèmes d'entreprise. Il est lisible, mais souvent verbeux.
- Formats binaires : Ces formats enregistrent les données non pas en texte mais directement en octets, comme elles sont en mémoire. Ils sont généralement plus compacts et rapides à sérialiser/désérialiser, mais totalement illisibles pour un humain. On les utilise quand la performance maximale ou la taille minimale est importante, par exemple pour sauvegarder des données de jeu ou transmettre de gros volumes entre composants internes d'un système.
Le choix du format dépend de la tâche : est-il nécessaire que l'humain puisse lire facilement les données ? La vitesse et la taille sont-elles importantes ? Vers quelles plateformes transmettez-vous les données ? Pour l'échange entre systèmes différents, JSON et XML sont souvent préférés pour leur universalité. Pour le stockage interne à une même application, les formats binaires peuvent être plus rapides et efficaces.
Comme vous le voyez, la sérialisation est un outil puissant qui est à la base de beaucoup d'applications modernes. Elle permet à nos programmes de "se souvenir" des données entre les exécutions, de communiquer entre eux et de gérer efficacement des informations complexes. Dans les prochaines leçons, on ne parlera plus de "magie", on va apprendre à l'utiliser avec les bibliothèques .NET ! Préparez-vous, ça va être intéressant !
GO TO FULL VERSION