2010-02-05 6 views
13

J'ai un scénario dans lequel j'ai une ressource de classe qui a deux autres classes imbriquées; Action et ResourceURL. J'ai besoin d'écrire xmlserializer personnalisé pour Resource et Action mais pas pour ResourceURL. J'ai implémenté IXmlSerializable pour les deux. Le problème est que lorsque Resource est sérialisé, j'appelle Action.WriteXML (XmlWriter) pour obtenir la forme sérialisée d'Action, mais je ne peux pas obtenir la forme sérialisée de ResourceURL. Les balises deviennent tout foiré et ajoute également une balise.XmlSerialization personnalisé pour les objets imbriqués/enfants

Alors, comment puis-je sérialiser un objet qui a la sérilisation client pour certains objets imbriqués, mais pas pour d'autres?

Répondre

17

Voici une méthode WriteXml exemple:

void IXmlSerializable.WriteXml(XmlWriter writer) 
    { 
     // Simple string value: 
     writer.WriteAttributeString("Name", this.Name); 

     // Object without IXmlSerializable implementation: 
     writer.WriteStartElement("NonCustomObject"); 
     new XmlSerializer(NonCustomObjectType).Serialize(writer, this.NonCustomObject); 
     writer.WriteEndElement(); 

     // Object with IXmlSerializable implementation: 
     writer.WriteStartElement("CustomObject"); 
     (this.CustomObject as IXmlSerializable).WriteXml(writer); 
     writer.WriteEndElement(); 
    } 

Voici une méthode ReadXml correspondante:

void IXmlSerializable.ReadXml(XmlReader reader) 
    { 
     // Simple string value 
     this.Name = reader.GetAttribute("Name"); 

     // Object without IXmlSerializable implementation here: 
     reader.ReadStartElement(); 
     if (reader.Name == "NonCustomObject") 
     { 
      reader.ReadStartElement(); 
      this.NonCustomObject = new XmlSerializer(NonCustomObjectType).Deserialize(reader); 
      reader.ReadEndElement(); 
     } 

     // Object with IXmlSerializable implementation here: 
     reader.ReadStartElement(); 
     if (reader.Name == "CustomObject") 
     { 
      (this.CustomObject as IXmlSerializable).ReadXml(reader); 
      reader.ReadEndElement(); 
     } 
    } 
+0

'deserialize()' retourne 'object' comme un type - vous devez jeter pour obtenir le type correct (c'est ici que les templates C++ et les génériques Java gagnent). – Guss

+0

@Guss comment? Les génériques .NET sont largement supérieurs aux génériques Java grâce au support CLR. Les templates C++ sont encore pires car ils nécessitent à l'avance la compilation de toutes les variantes possibles. –

+0

@ Mr.TA - (a) vous n'avez pas contesté le problème que j'ai spécifié, et c'est un problème flagrant sérieux dans .Net; (b) Je ne comprends pas ce que CLR a à faire avec ça - les génériques sont censés vous aider pendant la compilation, il n'y a aucune raison de garder l'information après cela - son aide de "casting sûr"; (c) votre assertion sur C++ est incorrecte: les templates C++ sont compilés uniquement pour les types réellement utilisés. – Guss

Questions connexes