0

インターフェイスを使用して、単一の抽象スーパークラスから派生した一連のサブクラスWorldObjectを XMLにシリアライズしようとしていIXmlSerializableます。クラスが逆シリアル化されているときにいくつかのイベントをサブスクライブする必要があるため、このインターフェイスを使用する必要があります。

この回答を使用して、次のコードを思いつきました。

[XmlInclude(typeof(SubType1))
,XmlInclude(typeof(SubType2))] // etc, includes all subtypes
public abstract class WorldObject : IComparable, IXmlSerializable

public void WriteXml(System.Xml.XmlWriter writer)
{
    Type[] extraTypes = new Type[8];
    // (...) adding types to array here
    var worldObjectSerializer = new XmlSerializer(typeof(List<WorldObject>), extraTypes);
}

が初期化される最後の行でXmlSerializer実行時エラーがスローされます: System.MissingMethodException: 抽象クラス 'Namespace.WorldObject' を作成できません。typeof(WorldObject)の代わりに使用しようとすると、同じエラーがスローされますtypeof(List<WorldObject>)

ここに示すように、すべてのクラスで XMLRoot を同じ値に設定しようとしましたが、エラーは解決しません。

4

1 に答える 1

1

例外を取り除く方法は見つかりませんでしたが、回避策を見つけました。このソリューションは、タイプを名前として独自の要素ラッパーを記述し、WriteXml 関数を呼び出して、終了要素を書き込むだけです。

foreach (WorldObject wO in list)
        {
             writer.WriteStartElement(wO.GetType().ToString());

             wO.WriteXml(writer);

             writer.WriteEndElement();
        }

これにより、抽象クラスの具体的な実装も逆シリアル化できます。はwO.GetType().ToString()、具体的なクラスと名前空間を含む文字列を作成します。XmlSerializer次に、次のように、要素ラッパー名から型が収集される場所を作成できます。

Type t = Type.GetType(reader.LocalName);
XmlSerializer worldObjectSerializer = new XmlSerializer(t, new XmlRootAttribute(reader.LocalName));
于 2014-04-08T19:02:56.303 に答える