Serialisierung von privaten Mitgliedsdaten
-
03-07-2019 - |
Frage
Ich versuche, ein Objekt in XML serialisiert werden, die eine Reihe von Eigenschaften aufweist, von denen einige nur lesbar.
public Guid Id { get; private set; }
Ich habe die Klasse markiert [Serializable] und ich habe den ISerializable-Schnittstelle implementiert.
Unten ist der Code, den ich mit meinem Objekt serialisiert werden.
public void SaveMyObject(MyObject obj)
{
XmlSerializer serializer = new XmlSerializer(typeof(MyObject));
TextWriter tw = new StreamWriter(_location);
serializer.Serialize(tw, obj);
tw.Close();
}
Leider fällt es mit dieser Meldung auf der ersten Zeile über.
InvalidOperationException wurde nicht behandelt: Es kann keine temporäre Klasse (Ergebnis = 1) erzeugen. Fehler CS0200: Eigenschaft oder Indexer ‚MyObject.Id‘ kann nicht zugewiesen werden - es ist nur lesen
Wenn ich die Id-Eigenschaft auf öffentlichen gesetzt funktioniert es gut. Kann mir jemand sagen, ob ich etwas mache, oder zumindest, wenn sein überhaupt möglich?
Lösung
könnten Sie verwenden DataContractSerializer
(aber beachten Sie XML-Attribute verwenden können - nur XML-Elemente):
using System;
using System.Runtime.Serialization;
using System.Xml;
[DataContract]
class MyObject {
public MyObject(Guid id) { this.id = id; }
[DataMember(Name="Id")]
private Guid id;
public Guid Id { get {return id;}}
}
static class Program {
static void Main() {
var ser = new DataContractSerializer(typeof(MyObject));
var obj = new MyObject(Guid.NewGuid());
using(XmlWriter xw = XmlWriter.Create(Console.Out)) {
ser.WriteObject(xw, obj);
}
}
}
Alternativ können Sie IXmlSerializable
implementieren und alles tun, selbst. - aber das funktioniert mit XmlSerializer
, zumindest
Andere Tipps
Sie könnten die System.Runtime.Serialization.NetDataContractSerializer
verwenden. Es ist leistungsfähiger und behebt einige Probleme des klassischen XML Serializer.
Beachten Sie, dass es verschiedene Attribute für diese ein.
[DataContract]
public class X
{
[DataMember]
public Guid Id { get; private set; }
}
NetDataContractSerializer serializer = new NetDataContractSerializer();
TextWriter tw = new StreamWriter(_location);
serializer.Serialize(tw, obj);
Edit:
Update auf Basis von Marc Kommentar: Sie sollten wahrscheinlich System.Runtime.Serialization.DataContractSerializer
für Ihren Fall verwenden, um eine saubere XML zu erhalten. Der Rest des Codes ist das gleiche.
Lesen Sie nur Felder werden nicht serialisiert werden, um die XmlSerializer
verwenden, ist dies aufgrund der Natur des readonly
Schlüsselwort
Von MSDN:
Die Read-only Schlüsselwort ist ein Modifikator, die Sie auf Felder verwenden können. Wenn eine Felddeklaration einen Nur-Lese-Modifikator enthält, Zuweisungen, die durch die Deklaration eingeführt Felder können nur im Rahmen der Deklaration oder in einem Konstruktor in der gleichen Klasse auftreten.
So ... Sie würde ziemlich viel um die Felder Wert in der Default-Konstruktor zu setzen ...
Es ist nicht möglich, mit diesem speziellen Serialisierung-Modus (die anderen Kommentare zu Abhilfen sehen). Wenn Sie wirklich Ihre Serialisierung-Modus verlassen wollen, wie sie ist, haben Sie rund um die Rahmen Einschränkungen auf diesem arbeiten. Sehen Sie diese Beispiel
esentially, die Eigenschaft public
markieren, aber eine Ausnahme auslösen, wenn es zu einem anderen Zeitpunkt als Deserialisierung zugegriffen wird.