Ich habe ein Objekt, das ich versuche, in XML zu serialisieren. In diesem Objekt befindet sich eine Liste eines generischen Typs (abstrakte Klasse). Jeder Eintrag in dieser Liste könnte eine andere Klasse sein, aber alle von der abstrakten Basisklasse erben:Serialisieren Sie eine polymorphe Liste mit demselben Typnamen
public abstract class animal
{
public string type { get; set; }
}
public class cat:animal
{
public string size { get; set; }
public string furColor { get; set; }
}
public class fish:animal
{
public string size { get; set; }
public string scaleColor { get; set; }
}
Wenn ich die Liste Serialisierung, ich will es wie folgt aussehen:
<animal type="cat">
<size>medium</size>
<furColor>black</furColor>
</animal>
<animal type="fish">
<size>small</size>
<scaleColor>silver</scaleColor>
</animal>
I habe die einfache lösung ausprobiert:
Aber es wirft einen Fehler, weil es nicht den Objekttyp "Katze" erwartet. Das Hinzufügen des [XmlInclude] -Tags zu der Basisklasse, der abgeleiteten Klasse oder der gesamten enthaltenden Klasse (nennen wir es zoo) hilft hier nicht.
kann ich die typeof Bezeichnung für eine einzelne Klasse verwenden:
[XmlElement("Animal", typeof(cat))]
public List<animal> Animals { get; set; }
und dies funktioniert, wie ich es will, solange ich nur Katzen verwenden. In der Minute, in der ich einen Fisch in die Mischung gebe, explodiert er mit dem gleichen Fehler (ohne Fische zu erwarten).
Ich kann mehrere typeof hinzufügen Attribute:
[XmlElement("Animal")]
[XmlElementAttribute(typeof(cat))]
[XmlElementAttribute(typeof(fish))]
public List<animal> Animals { get; set; }
und diese kompiliert, aber ignoriert die Elementnamen und serialisiert die Objekte als <cat> </cat>
und <fish> </fish>
verbunden, die nicht akzeptabel ist.
ich versucht habe sogar mehr [XmlElement] Hinzufügen von Tags:
[XmlElement("Animal", typeof(cat))]
[XmlElement("Animal", typeof(fish))]
public List<animal> Animals { get; set; }
Dies wirft eine andere Ausnahme, diesmal, dass die Objekte „cat“ und „Fisch“ verwenden beide den Typen „Tier“ in der gleiche Umfang.
Kann mir jemand einen Weg vorstellen?
UPDATE Nach ein wenig mehr zu graben, fand ich This SO post, die den Namespace auf die Basisklasse schlägt vor, fügt hinzu:
[XmlRoot(Namespace="myNamespace")]
[XmlInclude(typeof(cat))]
[XmlInclude(typeof(fish))]
public abstract class animal
Serialisierung dies folgende Ausbeuten:
<animal xsi:type="cat" type="cat">
...
</animal>
<animal xsi:type="fish" type="fish">
...
</animal>
Wo xsi: type = "cat" bezieht sich auf den Namen der Klasse und type = "cat" bezieht sich auf das erstellte type-Attribut innerhalb der Basisklasse (siehe das oberste Beispiel). Das ist so nahe zu dem, was ich brauche, und ich fürchte, ich kann nur leiden an Unerfahrenheit hier, aber gibt es eine Möglichkeit, die Xsi: Typ Attributliste loswerden?
Ich habe Ihren Titel bearbeitet. Bitte lesen Sie "[Sollten die Fragen" Tags "in ihren Titeln enthalten?] (Http://meta.stackexchange.com/questions/19190/)", wobei der Konsens "nein, sie sollten nicht" lautet. –
Entschuldigung, ich habe das in den Richtlinien verpasst. Danke für das Heads-up. – JesseF
Eine Teillösung gefunden, siehe das Update unten für Details – JesseF