Hallo,
ich habe eine Klasse Foo, welche serialisiert werden kann, diese hat ein Property Controller vom Typ ControllerMaster, so ungefähr:
[Serializable]
class Foo
{
public ControllerMaster Controller { get; set; }
}
Die Referenz auf das Property ist komplex und aufwendig zu serialisieren. Ich kann jedoch den Controller sehr leicht in eine String-Representation umwandeln (kein ToString()) und beim Deserialsieren den String wieder in das Objekt wandeln.
Gibt es ein Attribut oder ähnliches, was bei der Serialisierung und Deserialisierung eine Methode aufruft, die bei der Serialisierung einen String und bei der Deserialisierung ein Objekt vom Typ ControllerMaster zurück gibt?
Ich würde nach Möglichkeit ungern ein verstecktes Property mit der String-Represenation vorhalten müssen, was anstelle des eigentlichen Properties serialisiert wird.
Life is a short
Hi,
benutze einfach ISerializable für deine Klasse und implementiere GetObjectData entsprechend.
Außerdem benötigt die Klasse dann noch einen Konstruktor(SerializationInfo, StreamingContext) zum deserialisieren.
Hallo Seikilos,
[Serializable] betrifft eh nur die binäre Serialisierung. Und die binäre Serialisierung betrifft nur Felder, keine Properties (siehe Untersch. Behandlung der Objektdaten bzgl. Modifizierer bei Serialisierung in den versch. Formaten).
Mach aus der automatischen Property eine normale und ein Feld. Dann kannst das ControllerMaster-Feld mit [NonSerialized] kennzeichnen. Dann legst du, auch wenn dir das nicht gefällt, noch ein Feld vom Typ String an. Im Setter der Property füllst du nicht nur das ursprüngliche Feld, sondern auch das String-Feld. Im Getter fragst du ab, ob das ursprüngliche Feld null ist. Wenn das so ist, aber das String-Feld nicht leer ist, erzeugst du den ControllerMaster anhand des Strings neu. Das ist natürlich nur eine Skizze.
Das dürfte deutlich einfacher sein, als ISerializable und den passenden Konstruktor zu definieren.
herbivore
Ich hatte mal ein Beispiel, wo die Serialisierung über ein Attribut (ähnlich dem KnownTypeAttribute von WCF, nur eben für den XmlSerializer) und eine zweite Klasse mit impliziten Konvertierungsoperatoren gearbeitet hat - leider finde ich grade nichts passendes, weil mir auch der Attributname entfallen ist...
Meinst du OnSerializedAttribute/OnDeserializeAttribute aus dem System.Runtime.Serialization Namespace?
Nicht ganz, weils auf Xml-Serialisierung bezogen war - da dürfts aber das XmlIncludeAttribute die Type-Property von XmlElement
und Co. sein; Danke für den Stoß in die richtige Richtung.
Sieht dann in etwa so aus (nicht getestet, ist aus dem Kopf abgeschrieben):
public class SerializableFoo
{
public string MyProperty { get; set; }
public static implicit operator SerializableFoo(Foo foo) { ... }
public static implicit operator Foo(SerializableFoo serFoo) { ... }
}
[XmlRoot("bar")]
public class Bar
{
[XmlElement("foo", Type = typeof(SerializableFoo))]
public Foo NotSoSimple { get; set; }
}
Abgesehen vom XmlInclude
Type
-Property hat die Klasse Bar
(oder auch die Klasse Foo
) keine Logik zur Konvertierung drin - die dort ja eventuell auch nicht reingehört, wenns neben der Serialisierung nicht auch einem anderen Zweck dient.
Fand ich vom Konzept her damals kuhl, wenn auch das XmlInclude
Type
-Property und die Operatoren ein wenig nach Missbrauch der Features riechen 😃
Edit: Grade mal wieder auf ein Problem gestoßen und obige Technik angewandt; dabei hat sich rausgestellt dass die Type
-Property gemeint war, nicht das XmlIncludeAttribute
- Sample usw. korrigiert