public class Options { public FolderOption FolderOption { set; get; } public Options() { FolderOption = new FolderOption(); } public void Save() { XmlSerializer serializer = new XmlSerializer(typeof(Options)); TextWriter textWriter = new StreamWriter(@"C:\Options.xml"); serializer.Serialize(textWriter, this); textWriter.Close(); } public void Read() { XmlSerializer deserializer = new XmlSerializer(typeof(Options)); TextReader textReader = new StreamReader(@"C:\Options.xml"); //this = (Options)deserializer.Deserialize(textReader); textReader.Close(); } } } I managed to Save without problem, all members of FolderOption are deserialized. But the problem is how to read it back? The line - //this = (Options)deserializer.Deserialize(textReader); won't work. Edit: Any solution to this problem? Can we achieve the same purpose without assigning to this? That is deserialize Options object back into Option. I am lazy to do it property by property. Performing on the highest level would save of lot of effort.
7 Réponses :
voir XMLSerializer.Desérialize Méthode : Vous pouvez créer une méthode statique comme suit: ce qui précède peut être appelé comme suit: p>
1) Veuillez lire sa question plus attentivement. 2) -1 Pour ne pas utiliser de blocs "en utilisant".
Vous avez toujours besoin d'une utilisation autour de la xmlreader.
Un objet ne peut pas désérialiser elle-même, par définition: il existe déjà, et la désérialisation crée une nouvelle instance du type.
Il est parfois logique de créer une nouvelle instance vide d'une classe, puis remplissez-la avec des informations. apporté de XML. L'instance pourrait également être "presque vide". Vous pouvez le faire, par exemple, afin de charger les préférences des utilisateurs ou en général, de régler l'instance à la manière dont elle était utilisée. L'état "vide" ou "presque vide" de l'instance serait un état valide pour la classe: il ne saurait tout simplement pas savoir quel état il avait l'habitude d'être persisté. P>
En outre, je vous recommande d'entrer dans l'habitude de mettre en œuvre des blocs "à l'aide": p> Cela garantira que les textreaders sont éliminés même si une exception est lancée. C'est pourquoi les appels proches ne sont plus nécessaires. P> P>
Cela fonctionnera si votre type d'options est une structure, comme vous pouvez altérer une structure elle-même.
Si les options sont une classe (type de référence), vous ne pouvez pas attribuer à l'instance actuelle d'un type de référence avec dans ce cas. Vous suggère d'écrire une classe d'assistance et de mettre vos méthodes de lecture et d'enregistrement là-bas, telles que ceci p> puis consommez-le de votre appelant, de lire et de sauvegarder des objets, à la place de essayant de la classe. p> et mettre le xmlSerializerhelper dans l'espace de noms de votre util, il est réutilisable et fonctionnera avec n'importe quel type. P> P>
-1 Pour ne pas mettre en œuvre des blocs "en utilisant", et pour ne pas utiliser de génériques.
Utilisation (xmlSerializer désérialiszer = nouveau xmlSerializer (_type)) ne fonctionne pas. XMLSerializer n'a pas mis en œuvre Idisposable. La bonne devrait être comme ce que la réponse de John, mettant xmlsérialisateur en dehors de l'utilisation du bloc.
Oups, oublié un instant que XmlSerializer n'a pas mis en œuvre Idisposable, corrigé :)
Merci pour la mise à jour. Au moins maintenant, je sais ce que John signifie par "n'utilisant pas de génériques".
L'ensemble du point d'utilisation des génériques est d'éviter de coulée. // dans la classe d'assistance annulation publique sauvegarde (chemin de chaîne, t @Object); public t lire (chemin de cordes); Rendez le résultat; // en classe appelante obj = helper.read ("Yourpath"); // pas de casting requis
Oui, maintenant j'ai écrit que dans l'IDE et que je m'assurait qu'il s'agisse de la compilation, lol;)
Construisez votre puis changez votre code d'appel aussi que quelque chose comme ça: p> vous faites quelque chose comme ceci: p> La belle différence est qu'il est impossible de disposer d'un objet d'options qui n'a pas de données derrière elle. p> p> .Read () code> comme une fonction statique qui renvoie l'objet de lecture:
Je suis d'accord, cet imo est la solution la plus propre qui répond à la question.
Je ne peux pas commenter pour les autres, mais cela correspond au meilleur projet actuel ... très soigné.
Je suis allé pour cette approche (en VB) Je peux alors utiliser quelque chose comme ceci: p> et appelez-le comme ceci: p> ou même mieux (si j'ajoute le constructeur nécessaire): p> Il semble beau et propre Pour moi et fonctionne bien dans ma situation. P> acclamations p> p>
Je pense que le moyen le plus simple de sérialiser et de désérialiser un objet est d'utiliser une classe statique avec les deux méthodes suivantes. Nous avons également besoin d'une classe nommée StringWriterWithecoding pour définir le codage de la chaîne XML, car la propriété de codage de la classe StringWriter standard est réadonnée. (trouvé ici: http: // devrogroj20 .blogspot.com / 2008/02 / ECRIDE-XML-OUTF-8-CODING-UTILISATION.HTML )
//serialize MyClass myClass = new MyClass(); string xml = GenericXmlSerializer.Serialize<MyClass>(myClass, Encoding.Unicode); //deserialize MyClass myClass2 = GenericXmlSerializer.Deserialize<MyClass>(xml);
Je suis fan de méthodes d'extension, donc j'utilise cela toujours:
[XmlElement("NameOfTheElementYouWant")] [XmlAttribute("NameOfTheAttributeYouWant")] [XmlText]