XML にシリアライズしようとしているオブジェクトがあります。このオブジェクトの内部には、ジェネリック型 (抽象クラス) のリストがあります。このリストの各項目は異なるクラスである可能性がありますが、すべてが抽象基本クラスから継承されています。
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; }
}
リストをシリアル化すると、次のようになります。
<animal type="cat">
<size>medium</size>
<furColor>black</furColor>
</animal>
<animal type="fish">
<size>small</size>
<scaleColor>silver</scaleColor>
</animal>
私は簡単な解決策を試しました:
[XmlElement("Animal")]
public List<animal> Animals { get; set; }
しかし、オブジェクト タイプ「cat」が想定されていないため、エラーがスローされます。[XmlInclude] タグを基本クラス、派生クラス、またはそれを含むクラス全体 (zoo と呼びましょう) のいずれかに追加しても、これは役に立ちません。
単一のクラスに typeof 指定を使用できます。
[XmlElement("Animal", typeof(cat))]
public List<animal> Animals { get; set; }
猫だけを使用している限り、これは私が望むように適切に機能します。繰り返しますが、ミックスに魚を追加すると、同じエラーで爆発します (魚を期待していません)。
複数の typeof 属性を追加できます。
[XmlElement("Animal")]
[XmlElementAttribute(typeof(cat))]
[XmlElementAttribute(typeof(fish))]
public List<animal> Animals { get; set; }
これはコンパイルされますが、要素名を無視し、オブジェクトをそれぞれ<cat> </cat>
およびとしてシリアル化します<fish> </fish>
が、これは受け入れられません。
複数の [XmlElement] タグを追加してみました:
[XmlElement("Animal", typeof(cat))]
[XmlElement("Animal", typeof(fish))]
public List<animal> Animals { get; set; }
これは別の例外をスローします。今回は、オブジェクト「cat」と「fish」の両方が同じスコープでタイプ「Animal」を使用します。
誰でもこれを回避する方法を考えることができますか?
UPDATEもう少し掘り下げた後、名前空間を基本クラスに追加することを提案するこのSO投稿を見つけました:
[XmlRoot(Namespace="myNamespace")]
[XmlInclude(typeof(cat))]
[XmlInclude(typeof(fish))]
public abstract class animal
これをシリアル化すると、次のようになります。
<animal xsi:type="cat" type="cat">
...
</animal>
<animal xsi:type="fish" type="fish">
...
</animal>
ここで、xsi:type="cat"はクラスの名前を指し、type="cat"は基本クラス内で作成されたタイプ属性を指します (一番上の例を参照)。これは私が必要とするものに非常に近いものであり、ここで経験不足に苦しんでいるだけかもしれませんが、xsi:type 属性のリストを取り除く方法はありますか?