39 votes

Qu'est-ce qu'un graphe d'objets et comment en sérialiser un ?

J'ai lu dernièrement des articles sur la sérialisation. J'ai lu que lorsque j'utilise XmlSerialization, je ne peux pas sérialiser les graphes d'objets. Qu'est-ce qu'un graphe d'objets et pourquoi je ne peux pas le sérialiser simplement ?

52voto

Marc Gravell Points 482669

Un graphe d'objets n'est pas un objet unique, mais plutôt un ensemble d'objets liés. Pour un exemple simple, considérons :

public class Node {
    public string Name {...}
    public Node Parent {...}
    public List<Node> Children {...}
}

où chaque enfant connaît le parent (et le parent connaît l'enfant).

Le problème est que xml est un arbre basé sur les propriétés des objets... et il veut juste les parcourir - c'est-à-dire avec le simple parent/enfant :

  • A (sait que B est son enfant)
    • B (sait que A est son parent)

qui serait sérialisé comme :

<Node>
  <Name>A</Name>
  <!-- no Parent as A is the top node, so null -->
  <Children>
     <Node>
        <Name>B</Name>
        <Parent>
           <Node>
              <Name>A</Name>
              *** boom ***

Vous pouvez voir que nous sommes revenus à A, donc nous sommes maintenant dans une boucle sans fin.

XmlSerializer peut sérialiser arbres de données, mais pas de graphiques complets. Vous pouvez marquer les propriétés à ignorer, par exemple :

[XmlIgnore]
public Node Parent {...}

Et maintenant, ça va fonctionner, mais nous devrons réparer le Parent après.

En revanche, certains autres sérialiseurs peuvent gérer les graphes ( DataContractSerializer sur demande). Pour ce faire, il suit les objets en fonction d'une clé unique, mais le résultat n'est pas celui que l'on attend d'un fichier xml ordinaire.

9voto

Andrew Shepherd Points 16670

Un graphe d'objets est un ensemble d'objets qui font référence les uns aux autres.

La sérialisation d'un graphe d'objets est délicate. Le sérialiseur doit attribuer un identifiant unique à chaque objet, puis remplacer les références par des identifiants uniques.

S'il s'agissait d'une sérialisation au format XML et de la gestion de graphes d'objets, il faudrait ajouter un attribut "OBJECT_ID" (ou un autre nom) à chaque élément. Cela serait très facile à casser : que se passerait-il si vous ajoutiez une propriété portant le même nom à la classe que vous sérialisez ?

La solution la plus simple est de ne pas le soutenir.

.NET fournit une sérialisation binaire qui traite ce problème ainsi que celui des références circulaires.

5voto

Pontus Gagge Points 12950

Un objet général graphique est constitué d'un ensemble d'objets détenant des références les uns aux autres. Si vous avez un arbre d'objets où il n'y a pas de liens en arrière, la sérialisation et la désérialisation sont simples. Avec un graphe général, le processus de (dé)sérialisation doit garder la trace de l'identité de chaque objet et utiliser une forme d'algorithme de marquage et de balayage pour s'assurer que les objets ne sont pas (dé)sérialisés deux fois.

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